package com.zmj.sy.mom.srv.aps.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import com.google.common.collect.Lists;
import com.zmj.sy.mom.srv.aps.bean.dto.wms.MesPicking;
import com.zmj.sy.mom.srv.aps.bean.entity.base.BaseEntity;
import com.zmj.sy.mom.srv.aps.bean.entity.base.ProcessChain;
import com.zmj.sy.mom.srv.aps.bean.entity.base.ProcessChainItem;
import com.zmj.sy.mom.srv.aps.bean.entity.order.*;
import com.zmj.sy.mom.srv.aps.bean.entity.resource.*;
import com.zmj.sy.mom.srv.aps.bean.entity.third.HexagonPackagePush;
import com.zmj.sy.mom.srv.aps.bean.entity.third.SinoCamPushDrawing;
import com.zmj.sy.mom.srv.aps.bean.entity.third.SinoCamPushPlan;
import com.zmj.sy.mom.srv.aps.bean.vo.aps.ApsNestHexagonItemReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.base.BaseIdsReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.base.BaseSelectItemResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.base.Result;
import com.zmj.sy.mom.srv.aps.bean.vo.change.*;
import com.zmj.sy.mom.srv.aps.bean.vo.nest.NestProPushHexReqVo;
import com.zmj.sy.mom.srv.aps.config.ProjectConfig;
import com.zmj.sy.mom.srv.aps.config.StrategyConfig;
import com.zmj.sy.mom.srv.aps.feign.WmsLtkApiClient;
import com.zmj.sy.mom.srv.aps.mapper.*;
import com.zmj.sy.mom.srv.aps.utils.MkBeanUtils;
import com.zmj.sy.mom.srv.aps.utils.PkgUtils;
import com.zmj.sy.mom.srv.aps.utils.SyExceptionUtils;
import com.zmj.sy.mom.srv.aps.utils.nest.HexagonNestRule;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@RequiredArgsConstructor
@Service
public class ChangeService {

    private final OrderBomMapper orderBomMapper;
    private final ApsWorkOrderMapper apsWorkOrderMapper;
    private final OrderPhaseMapper orderPhaseMapper;
    private final ApsWorkDetailMapper apsWorkDetailMapper;
    private final WmsService wmsService;
    private final PhaseMapper phaseMapper;
    private final GroupMapper groupMapper;
//    private final StationGroupMapper stationGroupMapper;
    private final StationMapper stationMapper;
    private final OrderPartMapper orderPartMapper;
    private final ImportMbdDxfMapper importMbdDxfMapper;
    private final WmsLtkApiClient wmsLtkApiClient;
    private final NestService nestService;
    private final HexagonPackagePushMapper hexagonPackagePushMapper;
    private final ImportErpMappingMapper importErpMappingMapper;
    private final SinoCamPushPlanMapper sinoCamPushPlanMapper;
    private final ApsOrderMapper apsOrderMapper;
    private final FactoryMapper factoryMapper;
    private final OrderMapper orderMapper;
    private final SinoCamPushDrawingMapper sinoCamPushDrawingMapper;
    private final ProcessChainMapper processChainMapper;
    private final ProjectConfig projectConfig;
    private final ApsDetailWeekdayMapper apsDetailWeekdayMapper;
    private final ProcessChainItemMapper processChainItemMapper;
    private final PhaseGroupMapper phaseGroupMapper;
    private final WorkDetailTaskMapper workDetailTaskMapper;
    private final HexagonNestRule hexagonNestRule;
    private final StrategyConfig strategyConfig;

    @Transactional
    public void partToComponent(BaseIdsReqVo reqVo) {
        for (Integer id : reqVo.getIds()) {

            ApsWorkOrder temp = apsWorkOrderMapper.selectById(id);

            // 修改为外购
            OrderBom orderBom = orderBomMapper.selectById(temp.getBomId());
            if (!(orderBom.getMaterType().equals("Platepart") || orderBom.getMaterType().equals("Component") )) {
                throw SyExceptionUtils.e("不是自制件!");
            }
            orderBom.setWorkChain("WL");
            orderBom.setMaterType("Component");
            orderBom.setReadyType(2);
            orderBomMapper.updateById(orderBom);

            // 删除工序
            List<OrderPhase> orderPhaseList = orderPhaseMapper.lambdaQuery().eq(OrderPhase::getBomId, orderBom.getId()).list();
            orderPhaseMapper.deleteByBomId(orderBom.getId());

            // 修改工单
            List<ApsWorkOrder> workOrderList = apsWorkOrderMapper.lambdaQuery().eq(ApsWorkOrder::getBomId, orderBom.getId()).list();
            for (ApsWorkOrder apsWorkOrder : workOrderList) {
                apsWorkOrder.setWorkChain(orderBom.getWorkChain());
                apsWorkOrder.setMaterType(orderBom.getMaterType());
                apsWorkOrder.setReadyType(orderBom.getReadyType());
                apsWorkOrderMapper.updateById(apsWorkOrder);
            }

            // 修改工单详情
            List<ApsWorkDetail> workDetailList = apsWorkDetailMapper.lambdaQuery().in(ApsWorkDetail::getApsWorkOrderId, workOrderList.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList())).list();
            for (OrderPhase orderPhase : orderPhaseList) {
                apsWorkDetailMapper.deleteByPhaseId(orderPhase.getId());
            }

            // 推送到立体库
            wmsService.partProcurement(orderBom.getOrderId(), 0);

            // 删除推送套料计划
            if (CollUtil.isNotEmpty(workDetailList)) {
                List<SinoCamPushPlan> pushPlanList = sinoCamPushPlanMapper.lambdaQuery().in(SinoCamPushPlan::getNestPlanId, workDetailList.stream().map(ApsWorkDetail::getId).collect(Collectors.toList())).list();
                for (SinoCamPushPlan plan : pushPlanList) {
                    sinoCamPushPlanMapper.deleteWithId(plan.getId());
                }
            }
        }


    }

    @Transactional
    public void componentToPart(ChangeComponentToPartReqVo reqVo) {

        List<ApsWorkOrder> apsWorkOrders = apsWorkOrderMapper.selectBatchIds(reqVo.getIds());
        if (apsWorkOrders.size() != reqVo.getIds().size()) {
            throw SyExceptionUtils.e("部分工单不存在，请刷新页面重试!");
        }

        Map<String, Integer> pickMap = new HashMap<>();
        for (ApsWorkOrder apsWorkOrder : apsWorkOrders) {
            pickMap.put(apsWorkOrder.getPickCode(), apsWorkOrder.getPickSeq());

            boolean component = apsWorkOrder.getMaterType().equals("Component");
            if (!component) {
                throw SyExceptionUtils.e("请选择正确的工单类型转换成自制!");
            }
        }

        List<Phase> phaseList = phaseMapper.lambdaQuery().isNotNull(Phase::getMyCode).isNotNull(Phase::getName).list();

        Map<String, Phase> phaseMap = phaseList.stream().collect(Collectors.toMap(Phase::getMyCode, e -> e));

        List<Integer> orderBomIdList = apsWorkOrders.stream().map(ApsWorkOrder::getBomId).collect(Collectors.toList());
        List<OrderBom> orderBomList = orderBomMapper.selectBatchIds(orderBomIdList);

        OrderBom orderBomFirst = orderBomList.get(0);
        OrderPart orderPart = orderPartMapper.lambdaQuery().eq(OrderPart::getPlmId, orderBomFirst.getPlmId()).one();
        if (orderPart == null) {
            orderPart = new OrderPart();
            orderPart.setType(2); // 普通件
            orderPart.setNetWeight(orderBomFirst.getMaterWeight());
            // orderPart.setArea(); // 面积
            orderPart.setWorkChain(orderBomFirst.getWorkChain()); // 工序链
            orderPart.setSource(orderBomFirst.getReadyType()); // 备料方式：1 自制  2 外购
            // orderPart.setCritical(); // 是否关键件 0不是 1是
            orderPart.setVersionCode(1L); // 版本号
            orderPart.setMaterType(orderBomFirst.getMaterType()); // 物料类别
            orderPart.setPlmId(orderBomFirst.getPlmId());
            // orderPart.setPngUrl(); // 零件PNG图纸路径
            // orderPart.setDxfUrl(); // 零件DXF图纸路径
            orderPart.setDrawing(orderBomFirst.getDrawing());
            String[] split = orderBomFirst.getStandards().split("δ");
            if (orderBomFirst.getTexture() != null) {
                orderPart.setTexture(orderBomFirst.getTexture());
            } else {
                orderPart.setTexture(split[0]);
            }
            if (orderBomFirst.getMaterHigh() != null) {
                orderPart.setThickness(new BigDecimal(orderBomFirst.getMaterHigh()));
            } else {
                orderPart.setThickness(new BigDecimal(split[1]));
            }
            // orderPart.setLength(); // 宽度
            // orderPart.setWidth(); // 长度


            String code = orderBomFirst.getPlmId();
            if (code.endsWith("_170")) {
                code = code.substring(0, code.indexOf("_170"));
            }
            ImportMbdDxf importMbdDxf = importMbdDxfMapper.lambdaQuery().eq(ImportMbdDxf::getPlmid, code).orderByDesc(ImportMbdDxf::getDocVersion).last("limit 1").one();
            orderPart.setDrawStatus(1); // 是否制图就绪，默认 未就绪
            orderPart.setVersionNum(importMbdDxf != null ? importMbdDxf.getDocVersion() : null); // 图纸版本号
            orderPart.setDrawUpdateTime(null); // 图纸更新时间
            orderPartMapper.insert(orderPart);

        } else {
            orderPart.setType(2); // 普通件
            orderPart.setNetWeight(orderBomFirst.getMaterWeight());
            orderPart.setWorkChain(orderBomFirst.getWorkChain()); // 工序链
            orderPart.setSource(orderBomFirst.getReadyType()); // 备料方式：1 自制  2 外购
            orderPart.setVersionCode(1L); // 版本号
            orderPart.setMaterType(orderBomFirst.getMaterType()); // 物料类别
            orderPart.setPlmId(orderBomFirst.getPlmId());
            orderPart.setDrawing(orderBomFirst.getDrawing());
            String[] split = orderBomFirst.getStandards().split("δ");
            if (orderBomFirst.getTexture() != null) {
                orderPart.setTexture(orderBomFirst.getTexture());
            } else {
                orderPart.setTexture(split[0]);
            }
            if (orderBomFirst.getMaterHigh() != null) {
                orderPart.setThickness(new BigDecimal(orderBomFirst.getMaterHigh()));
            } else {
                orderPart.setThickness(new BigDecimal(split[1]));
            }

            String code = orderBomFirst.getPlmId();
            if (code.endsWith("_170")) {
                code = code.substring(0, code.indexOf("_170"));
            }
            ImportMbdDxf importMbdDxf = importMbdDxfMapper.lambdaQuery().eq(ImportMbdDxf::getPlmid, code).orderByDesc(ImportMbdDxf::getDocVersion).last("limit 1").one();
            if (orderPart.getDrawStatus() == null || orderPart.getDrawStatus() <= 1) {
                orderPart.setDrawStatus(1); // 是否制图就绪，默认 未就绪
                orderPart.setVersionNum(importMbdDxf != null ? importMbdDxf.getDocVersion() : null); // 图纸版本号
                orderPart.setDrawUpdateTime(null); // 图纸更新时间
                orderPartMapper.updateById(orderPart);
            }
        }

        List<OrderPhase> orderPhaseList = reqVo.getPhaseList()
                .stream()
                .map(e -> {

                    Phase phase = phaseMap.get(e.getApsPhaseCode());

                    OrderPhase op = new OrderPhase();
                    op.setPhaseCode(e.getApsPhaseCode());
                    op.setPhaseName(phase.getName());
                    op.setWorkGroupNumber(e.getApsGroupCode());
                    op.setOpCode(e.getErpGroupCode());
                    op.setOp(e.getErpPhaseCode());
                    op.setWorkTime(new BigDecimal(e.getApsWorkTime()).multiply(new BigDecimal(60)).setScale(0, RoundingMode.HALF_UP).intValue());
                    op.setOriWorkTime(op.getWorkTime());

                    return op;
                })
                .collect(Collectors.toList());
        for (int i = 0; i < orderPhaseList.size(); i++) {
            orderPhaseList.get(i).setPhaseSeq(i+1);
        }

        Map<Integer, OrderBom> orderBomMap = orderBomList.stream().collect(Collectors.toMap(BaseEntity::getId, e -> e));

        String workChain = genWorkChain(orderPhaseList);

        // 补BOM数据
        List<OrderPhase> allPhaseList = new ArrayList<>();
        for (OrderBom ob : orderBomList) {
            ob.setWorkChain(workChain);
            ob.setMaterType("Platepart");
            ob.setReadyType(1);
            orderBomMapper.updateById(ob);

            for (OrderPhase orderPhase : orderPhaseList) {
                OrderPhase op = new OrderPhase();
                BeanUtils.copyProperties(orderPhase, op);
                op.setBomId(ob.getId());
                op.setOrderId(ob.getOrderId());
                op.setMaterName(ob.getMaterName());
                op.setMaterNo(ob.getMaterCode());
                op.setWorkChain(ob.getWorkChain());
                orderPhaseMapper.insert(op);

                allPhaseList.add(op);
            }
        }


        List<Group> groupList = groupMapper.lambdaQuery()
                .eq(Group::getType, 2)
                .isNotNull(Group::getMyCode)
                .isNotNull(Group::getName)
                .list();
        Map<String, Group> groupCodeMap = groupList.stream().collect(Collectors.toMap(Group::getMyCode, e -> e));

        List<Station> stationList = stationMapper.lambdaQuery()
                .in(Station::getGroupId, groupList.stream().map(BaseEntity::getId).collect(Collectors.toList())).list();
        Map<Integer, List<Station>> stationMap = stationList.stream().collect(Collectors.groupingBy(Station::getGroupId));

//        List<StationGroup> stationGroupList = stationGroupMapper.lambdaQuery().list();
//        Map<Integer, List<StationGroup>> stationGroupMap = stationGroupList.stream().collect(Collectors.groupingBy(StationGroup::getGroupId));


        // 补ApsWorkDetail数据
        Map<Integer, List<OrderPhase>> phaseBomIdMap = allPhaseList.stream().collect(Collectors.groupingBy(OrderPhase::getBomId));
        List<ApsWorkDetail> apsWorkDetails = new ArrayList<>();
        for (ApsWorkOrder workOrder : apsWorkOrders) {
            OrderBom orderBom = orderBomMap.get(workOrder.getBomId());
            workOrder.setWorkChain(orderBom.getWorkChain());
            workOrder.setMaterType(orderBom.getMaterType());
            workOrder.setReadyType(orderBom.getReadyType());
            apsWorkOrderMapper.updateById(workOrder);

            List<OrderPhase> bomPhaseList = phaseBomIdMap.get(workOrder.getBomId());
            for (OrderPhase orderPhase : bomPhaseList) {

                Group group = groupCodeMap.get(orderPhase.getWorkGroupNumber());
//                List<StationGroup> stationGroups = stationGroupMap.get(group.getId());
//                StationGroup stationGroup = stationGroups.get(0);
                List<Station> stations = stationMap.get(group.getId());
                Station station = stations.get(0);

                ApsWorkDetail apsWorkDetail = new ApsWorkDetail();
                apsWorkDetail.setOrderId(orderPhase.getOrderId());
                apsWorkDetail.setApsOrderId(workOrder.getApsOrderId());
                apsWorkDetail.setPhaseId(orderPhase.getId());
                apsWorkDetail.setApsWorkOrderId(workOrder.getId());
                apsWorkDetail.setApsWorkOrderPid(workOrder.getPid());
//                apsWorkDetail.setStationGroupId(stationGroup.getId());
                apsWorkDetail.setStationId(station.getId());
                apsWorkDetail.setGroupId(group.getId());
                apsWorkDetail.setWorkTime(orderPhase.getWorkTime());
                apsWorkDetail.setPhaseSeq(orderPhase.getPhaseSeq());
                apsWorkDetail.setPhaseCode(orderPhase.getPhaseCode());
                apsWorkDetail.setPhaseName(orderPhase.getPhaseName());
                apsWorkDetail.setPhaseCode(orderPhase.getPhaseCode());
                apsWorkDetail.setMaterNo(orderPhase.getMaterNo());
                apsWorkDetail.setMaterName(orderPhase.getMaterName());
                apsWorkDetail.setGroupCode(orderPhase.getWorkGroupNumber());
                apsWorkDetail.setOrderType(workOrder.getOrderType());
                apsWorkDetail.setPartCount(BigDecimal.valueOf(1));
                apsWorkDetail.setTotalCount(BigDecimal.valueOf(1));
                apsWorkDetail.setWorkTime(1);
                apsWorkDetail.setChangTime(0);
                apsWorkDetail.setEnterTime(0);
                apsWorkDetail.setOutTime(0);
                apsWorkDetail.setTotalWorkTime(1);
                apsWorkDetail.setProcessCount(new BigDecimal(0));
                apsWorkDetail.setFinishCount(new BigDecimal(0));
                apsWorkDetail.setStatus(2);
                apsWorkDetail.setDetailSeq(orderPhase.getPhaseSeq());
                apsWorkDetail.setReverseDetailId(null);
                apsWorkDetail.setPlanStartDateTime(LocalDateTime.now());
                apsWorkDetail.setPlanEndDateTime(LocalDateTime.now().plusDays(1));
                apsWorkDetail.setAppendFlag(3); // 从排程中脱离
                apsWorkDetail.setType(2);
                apsWorkDetail.setPlmId(orderBom.getPlmId());
                apsWorkDetailMapper.insert(apsWorkDetail);
                apsWorkDetails.add(apsWorkDetail);
            }
        }

        // 删除已推送外购件
        Map<String, Integer> pickCodeSeqMap = pickMap;

        // 通知立体库删除该订单下的外购件领料单
        try {
            List<MesPicking> pickList = new ArrayList<>();
            pickCodeSeqMap.forEach((key, value) -> {
                MesPicking p = new MesPicking();
                p.setPickListNo(Long.valueOf(key));
                p.setPickListItemNo(value);
                pickList.add(p);
            });
            Result result = wmsLtkApiClient.deletePickIng(pickList);
            log.info("立体库删除外购件领料单结果：", result);
        } catch (Exception e) {
            log.error("立体库删除外购件领料单异常：", e);
        }

        // 补套料数据（补充 push_plan 表数据）
        List<String> splitPhaseCode = Lists.newArrayList("JG", "HG");
        List<ApsWorkDetail> splitPhaseList = apsWorkDetails.stream().filter(e -> splitPhaseCode.contains(e.getPhaseCode())).collect(Collectors.toList());

        if (CollUtil.isNotEmpty(splitPhaseList)) {
            List<Integer> orderIds = splitPhaseList.stream().map(ApsWorkDetail::getOrderId).collect(Collectors.toList());
            BaseIdsReqVo idsReqVo = new BaseIdsReqVo();
            idsReqVo.setIds(orderIds);
            nestService.pushPartAdd(idsReqVo);
            addPlan(splitPhaseList);

            // 推送套料（补充 hex_package_push 表数据，推送到海克斯康调取 sendToMes 功能）

            Map<Integer, List<ApsWorkDetail>> orderDetailMap = splitPhaseList.stream().collect(Collectors.groupingBy(ApsWorkDetail::getOrderId));
            for (Integer orderId : orderDetailMap.keySet()) {
                List<ApsWorkDetail> detailList = orderDetailMap.get(orderId);
                List<String> nestPlanIds = detailList.stream().map(e -> {
                    return String.valueOf(e.getId());
                }).collect(Collectors.toList());
                List<HexagonPackagePush> hexPushList = hexagonPackagePushMapper.lambdaQuery().eq(HexagonPackagePush::getOrderId, orderId).list();
                if (CollUtil.isEmpty(hexPushList)) {
                    continue;
                }
                NestProPushHexReqVo hexReqVo = new NestProPushHexReqVo();
                hexReqVo.setNestPlanId(nestPlanIds);
                hexReqVo.setOrderId(orderId);
                hexReqVo.setCustName(hexPushList.get(0).getCustName());
                hexReqVo.setCustCode(hexPushList.get(0).getCustCode());
                hexReqVo.setMesOrderId(hexPushList.get(0).getMesOrderId());
                hexReqVo.setMesOrderCode(hexPushList.get(0).getMesOrderCode());
                nestService.pushManHex(hexReqVo);
            }
        }

    }

    public String genWorkChain(List<OrderPhase> orderPhaseList) {
        Map<String, Integer> phaseCodeMap = new HashMap<>();

        StringBuilder sb = new StringBuilder();

        for (OrderPhase orderPhase : orderPhaseList) {
            Integer compute = phaseCodeMap.compute(orderPhase.getPhaseCode(), (k, v) -> v == null ? 0 : v + 1);
            sb.append("-")
                    .append(orderPhase.getPhaseCode());
            if (compute >= 1) {
                sb.append(String.format("%02d", compute));
            }
        }

        sb.deleteCharAt(0);
        return sb.toString();
    }

    @Transactional(readOnly = true)
    public List<BaseSelectItemResVo> erpWorkCenter(ChangeErpWorkCenterReqVo reqVo) {
        List<ImportErpMapping> list = importErpMappingMapper.lambdaQuery().eq(StringUtils.hasText(reqVo.getErpOp()), ImportErpMapping::getErpOp, reqVo.getErpOp()).list();
        List<String> opCodeList = list.stream().map(ImportErpMapping::getErpOpCode).distinct().collect(Collectors.toList());
        return opCodeList.stream()
                .map(e -> {
                    BaseSelectItemResVo resVo = new BaseSelectItemResVo();
                    resVo.setText(e);
                    resVo.setValue(e);
                    return resVo;
                })
                .collect(Collectors.toList());
    }

    @Transactional(readOnly = true)
    public List<BaseSelectItemResVo> erpPhase(ChangeErpPhaseReqVo reqVo) {
        List<ImportErpMapping> list = importErpMappingMapper.lambdaQuery().eq(StringUtils.hasText(reqVo.getErpOpCode()), ImportErpMapping::getErpOpCode, reqVo.getErpOpCode()).list();
        List<String> opCodeList = list.stream().map(ImportErpMapping::getErpOp).distinct().collect(Collectors.toList());
        return opCodeList.stream()
                .map(e -> {
                    BaseSelectItemResVo resVo = new BaseSelectItemResVo();
                    resVo.setText(e);
                    resVo.setValue(e);
                    return resVo;
                })
                .collect(Collectors.toList());
    }

    @Transactional(readOnly = true)
    public ChangeErpToApsResVo erpToAps(ChangeErpToApsReqVo reqVo) {
        ImportErpMapping one = importErpMappingMapper.lambdaQuery()
                .eq(ImportErpMapping::getErpOpCode, reqVo.getErpOpCode())
                .eq(ImportErpMapping::getErpOp, reqVo.getErpOp())
                .one();

        if (one == null) {
            throw SyExceptionUtils.e("APS工序未找到该映射");
        }

        ChangeErpToApsResVo resVo = new ChangeErpToApsResVo();
        resVo.setApsPhaseCode(one.getMesWorkPhase());
        resVo.setApsPhaseName(one.getApsPhaseName());
        resVo.setApsGroupCode(one.getMesWorkCenter());

        return resVo;
    }

    public void addPlan(List<ApsWorkDetail> apsWorkDetailList) {

        List<Integer> orderIds = apsWorkDetailList.stream().map(ApsWorkDetail::getOrderId).collect(Collectors.toList());

        List<ApsOrder> apsOrders = apsOrderMapper.lambdaQuery().in(ApsOrder::getOrderId, orderIds).list();
        Map<Integer, ApsOrder> apsOrderIdMap = apsOrders.stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity()));

        // 取 ID
        List<ApsWorkOrder> apsWorkOrders = apsWorkOrderMapper.selectBatchIds(apsWorkDetailList.stream().map(ApsWorkDetail::getApsWorkOrderId).distinct().collect(Collectors.toList()));
        Map<Integer, ApsWorkOrder> apsWorkOrderIdMap = apsWorkOrders.stream().collect(Collectors.toMap(ApsWorkOrder::getId, Function.identity()));

        // 取 PID
        List<ApsWorkOrder> parentApsWorkOrders = apsWorkOrderMapper.selectBatchIds(apsWorkDetailList.stream().map(ApsWorkDetail::getApsWorkOrderPid).distinct().collect(Collectors.toList()));
        Map<Integer, ApsWorkOrder> apsWorkOrderPidMap = parentApsWorkOrders.stream().collect(Collectors.toMap(ApsWorkOrder::getId, Function.identity()));

        // 获取工厂信息
        List<Factory> factoryList = factoryMapper.selectList(null);
        Map<Integer, Factory> factoryMap = factoryList.stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity()));

        List<Order> orderList = orderMapper.lambdaQuery().in(BaseEntity::getId, orderIds).list();

        // 保存计划信息
        savePlanInfo(apsWorkDetailList, factoryMap, orderList, apsOrderIdMap, apsWorkOrderPidMap, apsWorkOrderIdMap);

    }

    public void savePlanInfo(List<ApsWorkDetail> apsWorkDetailList, Map<Integer, Factory> factoryMap, List<Order> orderList, Map<Integer, ApsOrder> apsOrderIdMap, Map<Integer, ApsWorkOrder> apsWorkOrderPidMap, Map<Integer, ApsWorkOrder> apsWorkOrderIdMap) {

        List<SinoCamPushDrawing> sinoCamPushPushDrawList = sinoCamPushDrawingMapper.lambdaQuery().in(SinoCamPushDrawing::getPartId, apsWorkDetailList.stream().map(ApsWorkDetail::getPlmId).collect(Collectors.toList())).list();
        Map<String, SinoCamPushDrawing> sinoCamPushPushDrawMap = sinoCamPushPushDrawList.stream().collect(Collectors.toMap(SinoCamPushDrawing::getPartId, Function.identity(), (a, b) -> b));

        Map<Integer, Order> orderMap = orderList.stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity()));

        List<ApsWorkOrder> allApsWorkOrder = apsWorkOrderMapper.lambdaQuery().in(ApsWorkOrder::getOrderId, orderList.stream().map(Order::getId).collect(Collectors.toList())).list();
        Map<Integer, List<ApsWorkOrder>> orderApsWorkOrder = allApsWorkOrder.stream().collect(Collectors.groupingBy(ApsWorkOrder::getOrderId));
        Map<Integer, Map<Integer, ApsWorkOrder>> allApsWorkOrderMap = new HashMap<>();
        for (Integer orderId : orderApsWorkOrder.keySet()) {
            List<ApsWorkOrder> orderApsWorkOrderMap = orderApsWorkOrder.get(orderId);
            Map<Integer, ApsWorkOrder> apsWorkOrderMap = orderApsWorkOrderMap.stream().collect(Collectors.toMap(ApsWorkOrder::getId, Function.identity()));
            allApsWorkOrderMap.put(orderId, apsWorkOrderMap);
        }

        List<SinoCamPushPlan> pushPlans = sinoCamPushPlanMapper.lambdaQuery().in(SinoCamPushPlan::getOrderId, orderList.stream().map(Order::getId).collect(Collectors.toList())).list();
        Map<String, SinoCamPushPlan> pushPlanMap = pushPlans.stream().collect(Collectors.toMap(SinoCamPushPlan::getNestPlanId, Function.identity()));

        List<SinoCamPushPlan> pushPlanList = new ArrayList<>();
        // 构建推送参数和数据库记录信息
        for (ApsWorkDetail apsWorkDetail : apsWorkDetailList) {

            SinoCamPushPlan pushPlan = new SinoCamPushPlan();

            ApsWorkOrder current = apsWorkOrderIdMap.get(apsWorkDetail.getApsWorkOrderId());
            ApsWorkOrder parent = apsWorkOrderPidMap.get(current.getPid());
            ApsOrder apsOrder = apsOrderIdMap.get(apsWorkDetail.getApsOrderId());
            Order order = orderMap.get(apsWorkDetail.getOrderId());

            int id = current.getId();
//            String path = PkgUtils.gen(apsOrder.getSeq()) + "→";
            StringBuilder path = new StringBuilder();
            while (true) {
                Map<Integer, ApsWorkOrder> orderApsWorkOrderMap = allApsWorkOrderMap.get(order.getId());
                ApsWorkOrder pathCur = orderApsWorkOrderMap.get(id);
                if (ObjectUtils.isEmpty(pathCur) || pathCur.getPid() == null) {
//                    path = PkgUtils.gen(apsOrder.getSeq()) + path;
                    break;
                }
                ApsWorkOrder pathPar = orderApsWorkOrderMap.get(pathCur.getPid());
                path.insert(0, "→" + pathPar.getPlmId());
                id = pathPar.getId();
            }

            SinoCamPushDrawing pushDraw = sinoCamPushPushDrawMap.get(apsWorkDetail.getPlmId());

            pushPlan.setComponentId(parent.getPlmId());
            pushPlan.setComponentName(parent.getMaterName());
            pushPlan.setFactoryIdk(factoryMap.get(apsWorkDetail.getFactoryId()).getMyCode());
            pushPlan.setNeedDate(apsWorkDetail.getPlanStartDateTime());
            pushPlan.setNestPlanId(String.valueOf(apsWorkDetail.getId()));
            pushPlan.setPartId(current.getPlmId());
            pushPlan.setPartName(current.getMaterName());
            pushPlan.setPartType("1");
            pushPlan.setPlanAmount(apsWorkDetail.getTotalCount());
            pushPlan.setProcessingNo(PkgUtils.gen(apsOrder.getSeq()));
            pushPlan.setApsOrderId(apsWorkDetail.getApsOrderId());
            pushPlan.setProductId(StringUtils.hasText(order.getConstructNo())?order.getConstructNo():order.getOrderCode());
            pushPlan.setVersionBrief("V1");
            if (ObjectUtils.isEmpty(pushDraw) || pushDraw.getStatus() == 5) {
                pushPlan.setStatus(5);
                pushPlan.setErrorMsg("推送图纸异常。");
                pushPlan.setUniMaterCode(current.getPlmId() + "#A.0");
                pushPlan.setReplaceTexture(null);
                pushPlan.setReplaceThickness(null);
            } else {
                pushPlan.setStatus(1);
                pushPlan.setErrorMsg(null);
                pushPlan.setUniMaterCode(current.getPlmId() + "#" + pushDraw.getDrawVersion());
                pushPlan.setReplaceTexture(pushDraw.getTexture());
                pushPlan.setReplaceThickness(pushDraw.getThickNess());
            }
            pushPlan.setPlanFinishAmount(new BigDecimal(0));
            pushPlan.setOrderId(order.getId());
            pushPlan.setVersionNum(1);
            pushPlan.setConsumeStatus(0);
            pushPlan.setPath(path.toString());

            pushPlanList.add(pushPlan);

            if (pushPlanMap.get(pushPlan.getNestPlanId()) != null) {
                sinoCamPushPlanMapper.lambdaUpdate().eq(SinoCamPushPlan::getNestPlanId, pushPlan.getNestPlanId()).set(SinoCamPushPlan::getPath, pushPlan.getPath()).update();
                pushPlanList.remove(pushPlan);
            }

        }

        if (CollUtil.isEmpty(pushPlanList)) {
            return ;
        }
        sinoCamPushPlanMapper.insertBatchSomeColumn(pushPlanList);

    }

    @Transactional
    public void bomAdd(ChangeBomAddReqVo reqVo) {
        OrderBom orderBom = MkBeanUtils.copyProperties(reqVo, OrderBom.class);

//        if (reqVo.getReadyType() == null) {
//            throw SyExceptionUtils.e("没有备料方式");
//        }

        if (reqVo.getPid() == null) {
            throw SyExceptionUtils.e("请选择父节点");
        }

        OrderBom parent = orderBomMapper.selectById(reqVo.getPid());
        Order order = orderMapper.selectById(parent.getOrderId());
        ProcessChain processChain = processChainMapper.selectById(reqVo.getProcessChainId());

        if (!parent.getMaterType().equals("Assembly")) {
            throw SyExceptionUtils.e("父节点不是组件");
        }

        if(orderBom.getMaterType() == null){
            throw SyExceptionUtils.e("没有物料类型");
        }
        if (orderBom.getMaterType().equals("Platepart") && order.getOrderType().equals(3)) {
            throw SyExceptionUtils.e("外揽订单没有自制件!");
        }

        if (orderBom.getMaterType().equals("Component") || processChain.getMyCode().equals("WL")) {
            orderBom.setWorkChain("WL");
            orderBom.setReadyType(2);
            orderBom.setMaterType("Component");
        } else {
            orderBom.setWorkChain("");
            orderBom.setReadyType(1);
        }

        orderBom.setErpCode(reqVo.getErpCode());// 添加
        orderBom.setMaterCode(orderBom.getPlmId());
        orderBom.setTopFlag(0);
        orderBom.setModifyStatus(LocalDateTime.now().format(DatePattern.PURE_DATETIME_FORMATTER));
        orderBom.setOrderId(parent.getOrderId());
        orderBom.setFactoryNo(parent.getFactoryNo());
        orderBom.setLevel(parent.getLevel() + 1);
        orderBom.setTotalCount(parent.getTotalCount().multiply(orderBom.getPartCount()));
        orderBom.setAssemblyPath(parent.getAssemblyPath() + "/" + orderBom.getMaterCode());
        orderBom.setMaterWeight(reqVo.getWeight());
        orderBom.setMaterHigh(reqVo.getMaterHigh());
        if (!StringUtils.hasText(orderBom.getDrawing())) {
            orderBom.setDrawing(orderBom.getPlmId().replace("_170", ""));
        }

        orderBom.setWorkChain(processChain.getMyCode());
        if (orderBom.getMaterType().equals("Platepart")) {
            orderBom.setStandards(orderBom.getTexture() + "δ" + orderBom.getMaterHigh());
            if(orderBom.getMaterWeight() == null){
                throw SyExceptionUtils.e("自制件重量必须填写");
            }
        } else if (orderBom.getMaterType().equals("Assembly")){
            orderBom.setStandards("组件");
        }

        orderBomMapper.insert(orderBom);

        if (order.getOrderStatus() <= 3 && orderBom.getReadyType().equals(2)) {
            return ;
        }

        List<ProcessChainItem> itemList = processChainItemMapper.lambdaQuery().eq(ProcessChainItem::getChainId, reqVo.getProcessChainId()).orderByAsc(ProcessChainItem::getSeq).list();
        List<PhaseGroup> list = phaseGroupMapper.lambdaQuery().in(PhaseGroup::getPhaseCode, itemList.stream().map(ProcessChainItem::getMyCode).distinct().collect(Collectors.toList())).list();
        Map<String, List<PhaseGroup>> phaseGroupMap = list.stream().collect(Collectors.groupingBy(PhaseGroup::getPhaseCode));

        List<OrderPhase> orderPhaseList = itemList.stream()
                .map(e -> {
                    OrderPhase item = new OrderPhase();
                    item.setBomId(orderBom.getId());
                    item.setOrderId(orderBom.getOrderId());
                    item.setWorkChain(orderBom.getWorkChain());
                    item.setPhaseName(e.getName());
                    item.setPhaseCode(e.getMyCode());
                    item.setPhaseSeq(e.getSeq());
                    item.setMaterNo(orderBom.getMaterCode());
                    item.setMaterName(orderBom.getMaterName());
                    if (item.getPhaseCode().equals("FM")) {
                        item.setWorkGroupNumber("4-3_FM_00");
                        item.setWorkTime(0);
                    } else if (item.getPhaseCode().equals("PT")) {
                        item.setWorkGroupNumber("4-3_PTX_00");
                        item.setWorkTime(10 * 60);
                    }

                    if(order.getOrderType().equals(4)){
                        item.setWorkTime(1);

                        List<PhaseGroup> phaseGroups = phaseGroupMap.get(e.getMyCode());
                        if(CollUtil.isNotEmpty(phaseGroups)){
                            item.setWorkGroupNumber(phaseGroups.get(0).getGroupCode());
                        }
                    }
                    item.setOriWorkTime(item.getWorkTime());
                    return item;
                })
                .collect(Collectors.toList());
        orderPhaseMapper.insertBatchSomeColumn(orderPhaseList);


        // 将 orderBom 进行写入，如果该条数据的父节点原本为普通节点，则要跟随修改其父节点的类别数据
        OrderPart one = orderPartMapper.lambdaQuery().eq(OrderPart::getPlmId, orderBom.getPlmId()).one();
        if (one == null) {
            OrderPart orderPart = new OrderPart();
            String code = orderBom.getPlmId();
            if (code.endsWith("_170")) {
                code = code.substring(0, code.indexOf("_170"));
            }
            ImportMbdDxf importMbdDxf = importMbdDxfMapper.lambdaQuery().eq(ImportMbdDxf::getPlmid, code).orderByDesc(ImportMbdDxf::getDocVersion).last("limit 1").one();

            orderPart.setPlmId(orderBom.getPlmId());
            // orderPart.setPngUrl(); // 零件PNG图纸路径
            // orderPart.setDxfUrl(); // 零件DXF图纸路径
            orderPart.setDrawing(orderBom.getDrawing());

            // orderPart.setArea(); // 面积
            if (!Objects.equals(orderBom.getMaterType(), "Platepart")) {
                orderPart.setTexture(orderBom.getTexture());
                if(orderBom.getMaterHigh() != null){
                    orderPart.setThickness(new BigDecimal(orderBom.getMaterHigh()));
                }
            } else {
                String[] split = orderBom.getStandards().split("δ");
                if (orderBom.getTexture() != null) {
                    orderPart.setTexture(orderBom.getTexture());
                } else {
                    orderPart.setTexture(split[0]);
                }
                if (orderBom.getMaterHigh() != null) {
                    orderPart.setThickness(new BigDecimal(orderBom.getMaterHigh()));
                } else {
                    orderPart.setThickness(new BigDecimal(split[1]));
                }
            }

            orderPart.setType(2); // 普通件
            orderPart.setNetWeight(reqVo.getWeight());
            orderPart.setWorkChain(orderBom.getWorkChain()); // 工序链
            orderPart.setSource(orderBom.getReadyType()); // 备料方式：1 自制  2 外购
            orderPart.setVersionCode(1L); // 版本号
            orderPart.setMaterType(orderBom.getMaterType()); // 物料类别
            orderPart.setDrawStatus(1); // 是否制图就绪，默认 未就绪
            orderPart.setVersionNum(importMbdDxf != null ? importMbdDxf.getDocVersion() : null); // 图纸版本号
            orderPart.setDrawUpdateTime(null); // 图纸更新时间
            // orderPart.setLength(); // 宽度
            // orderPart.setWidth(); // 长度
            // orderPart.setArea(); // 面积
            // orderPart.setCritical(); // 是否关键件 0不是 1是
            orderPartMapper.insert(orderPart);
            one = orderPart;
        }

        if(order.getOrderStatus() <= 3){
            return ;
        }

        if (order.getOrderStatus() < 6) {
            order.setOrderStatus(3);
            orderMapper.updateById(order);
            return ;
        }

        List<ApsWorkOrder> parentList = apsWorkOrderMapper.lambdaQuery().eq(ApsWorkOrder::getBomId, orderBom.getPid()).list();
        Map<Integer, ApsWorkOrder> workOrderMap = parentList.stream().collect(Collectors.toMap(ApsWorkOrder::getApsOrderId, e -> e));

        // 生成ApsWorkOrder
        List<ApsOrder> apsOrderList = apsOrderMapper.lambdaQuery().eq(ApsOrder::getOrderId, order.getId()).list();
        List<ApsWorkOrder> apsWorkOrderList = Stream.of(orderBom)
                .map(e -> {



                    ApsWorkOrder workOrder = MkBeanUtils.copyProperties(e, ApsWorkOrder.class);
                    workOrder.setBomId(e.getId());
                    workOrder.setBomPid(e.getPid());
                    workOrder.setId(null);
                    workOrder.setStatus(1);
                    workOrder.setFinishCount(new BigDecimal(0));
                    workOrder.setTotalCount(e.getTotalCount());
                    workOrder.setOrderType(order.getOrderType());
                    workOrder.setPlmId(e.getPlmId());
//                    apsBom.setApsOrderId(apsOrder.getId());
//                    apsBom.setOrderCount(e.getTotalCount().multiply(new BigDecimal(apsOrder.getOrderQty())));
                    return workOrder;
                })
                .flatMap(e ->
//                        ApsWorkOrder apsWorkOrder = workOrderMap.get(e.getPid());
                        apsOrderList
                                .stream()
                                .map(e1 -> {
                                    ApsWorkOrder awo = new ApsWorkOrder();
                                    BeanUtils.copyProperties(e, awo);
                                    awo.setApsOrderId(e1.getId());
                                    awo.setOrderCount(e.getTotalCount().multiply(new BigDecimal(e1.getOrderQty())));
                                    awo.setPlanStartDateTime(LocalDateTime.now());
                                    awo.setPlanEndDateTime(LocalDateTime.now());
                                    awo.setPid(workOrderMap.get(e1.getId()).getId());
                                    return awo;
                                })
                )
                .collect(Collectors.toList());
        apsWorkOrderMapper.insertBatch(apsWorkOrderList);

        // 状态大于等于6时，需要判断该件是自制还是外购，如果是外购则推送到立体库。
        if(!orderBom.getWorkChain().equals("WL")){
            return ;
        }

        // 把 apsWorkOrderList 赋值，并推送到立体库
        wmsService.partProcurement(order.getId(), 0);


    }

    @Transactional
    public void bomEdit(ChangeBomEditReqVo reqVo) {

        OrderBom oldBom = orderBomMapper.selectById(reqVo.getId());
        OrderBom parent = orderBomMapper.selectById(oldBom.getPid());
        OrderBom orderBom = MkBeanUtils.copyProperties(reqVo, OrderBom.class);
        orderBom.setId(reqVo.getId());

        if (reqVo.getReadyType() == null) {
            throw SyExceptionUtils.e("没有备料方式");
        }

        Order order = orderMapper.selectById(oldBom.getOrderId());
        ProcessChain processChain = processChainMapper.selectById(reqVo.getProcessChainId());

        if (orderBom.getMaterType() == null) {
            throw SyExceptionUtils.e("没有物料类型");
        }
        if (orderBom.getMaterType().equals("Platepart") && order.getOrderType().equals(3)) {
            throw SyExceptionUtils.e("外揽订单没有自制件!");
        }

        if (orderBom.getMaterType().equals("Component") || processChain.getMyCode().equals("WL")) {
            orderBom.setWorkChain("WL");
            orderBom.setReadyType(2);
            orderBom.setMaterType("Component");
        } else {
            orderBom.setMaterType(reqVo.getMaterType());
            orderBom.setWorkChain("");
            orderBom.setReadyType(1);
        }

        orderBom.setErpCode(reqVo.getErpCode());// 添加
        orderBom.setMaterCode(orderBom.getPlmId());
        orderBom.setTopFlag(oldBom.getTopFlag());
        orderBom.setModifyStatus(LocalDateTime.now().format(DatePattern.PURE_DATETIME_FORMATTER));
        orderBom.setOrderId(oldBom.getOrderId());
        orderBom.setFactoryNo(oldBom.getFactoryNo());
        orderBom.setLevel(oldBom.getLevel());
        orderBom.setTotalCount(parent.getTotalCount().multiply(orderBom.getPartCount()));
        orderBom.setAssemblyPath(parent.getAssemblyPath() + "/" + orderBom.getMaterCode());
        orderBom.setMaterWeight(reqVo.getWeight());
        orderBom.setMaterHigh(reqVo.getMaterHigh());
        if (!StringUtils.hasText(orderBom.getDrawing())) {
            orderBom.setDrawing(orderBom.getPlmId().replace("_170", ""));
        }

        orderBom.setWorkChain(processChain.getMyCode());
        if (orderBom.getMaterType().equals("Platepart")) {
            if(!(StringUtils.hasText(orderBom.getTexture()) && orderBom.getMaterHigh() != null)){
                throw SyExceptionUtils.e("没有材质或厚度");
            }
            orderBom.setStandards(orderBom.getTexture() + "δ" + orderBom.getMaterHigh());

            if(orderBom.getMaterWeight() == null){
                throw SyExceptionUtils.e("自制件重量必须填写");
            }
        } else if (orderBom.getMaterType().equals("Assembly")){
            orderBom.setStandards("组件");
        }

        orderBomMapper.updateById(orderBom);

        // 工序相同则不动，工序不同走以下流程：
        // 如果以前是别的件改为外购件，则删除以前的工序
        // 如果以前是外购件，要改成自制件或者组件，则需要添加工序
        if(!orderBom.getWorkChain().equals(oldBom.getWorkChain())){
            // 删除以前的工序
            List<OrderPhase> list1 = orderPhaseMapper.lambdaQuery().eq(OrderPhase::getBomId, orderBom.getId()).list();
            orderPhaseMapper.deleteByBomId(orderBom.getId());
            for (OrderPhase orderPhase : list1) {
                apsWorkDetailMapper.deleteByPhaseId(orderPhase.getId());
            }

            // 如果不是外购件，则新增工序
            if (!orderBom.getWorkChain().equals("WL")) {

                List<ProcessChainItem> itemList = processChainItemMapper.lambdaQuery().eq(ProcessChainItem::getChainId, reqVo.getProcessChainId()).orderByAsc(ProcessChainItem::getSeq).list();
                List<PhaseGroup> list = phaseGroupMapper.lambdaQuery().in(PhaseGroup::getPhaseCode, itemList.stream().map(ProcessChainItem::getMyCode).distinct().collect(Collectors.toList())).list();
                Map<String, List<PhaseGroup>> phaseGroupMap = list.stream().collect(Collectors.groupingBy(PhaseGroup::getPhaseCode));

                List<OrderPhase> orderPhaseList = itemList.stream()
                        .map(e -> {
                            OrderPhase item = new OrderPhase();
                            item.setBomId(orderBom.getId());
                            item.setOrderId(orderBom.getOrderId());
                            item.setWorkChain(orderBom.getWorkChain());
                            item.setPhaseName(e.getName());
                            item.setPhaseCode(e.getMyCode());
                            item.setPhaseSeq(e.getSeq());
                            item.setMaterNo(orderBom.getMaterCode());
                            item.setMaterName(orderBom.getMaterName());
                            if (item.getPhaseCode().equals("FM")) {
                                item.setWorkGroupNumber("4-3_FM_00");
                                item.setWorkTime(0);
                            } else if (item.getPhaseCode().equals("PT")) {
                                item.setWorkGroupNumber("4-3_PTX_00");
                                item.setWorkTime(10 * 60);
                            }

                            if(order.getOrderType().equals(4)){
                                item.setWorkTime(1);

                                List<PhaseGroup> phaseGroups = phaseGroupMap.get(e.getMyCode());
                                if(CollUtil.isNotEmpty(phaseGroups)){
                                    item.setWorkGroupNumber(phaseGroups.get(0).getGroupCode());
                                }
                            }
                            item.setOriWorkTime(item.getWorkTime());
                            return item;
                        })
                        .collect(Collectors.toList());
                orderPhaseMapper.insertBatchSomeColumn(orderPhaseList);
            }
        }



        if (order.getOrderStatus() <= 3 && reqVo.getReadyType().equals(2)) {
            return;
        }

        // 将 orderBom 进行写入，如果该条数据的父节点原本为普通节点，则要跟随修改其父节点的类别数据
        OrderPart one = orderPartMapper.lambdaQuery().eq(OrderPart::getPlmId, orderBom.getPlmId()).one();
        if (one == null) {
            OrderPart orderPart = new OrderPart();
            String code = orderBom.getPlmId();
            if (code.endsWith("_170")) {
                code = code.substring(0, code.indexOf("_170"));
            }
            ImportMbdDxf importMbdDxf = importMbdDxfMapper.lambdaQuery().eq(ImportMbdDxf::getPlmid, code).orderByDesc(ImportMbdDxf::getDocVersion).last("limit 1").one();

            orderPart.setPlmId(orderBom.getPlmId());
            // orderPart.setPngUrl(); // 零件PNG图纸路径
            // orderPart.setDxfUrl(); // 零件DXF图纸路径
            orderPart.setDrawing(orderBom.getDrawing());
            if (!Objects.equals(orderBom.getMaterType(), "Platepart")) {
                orderPart.setTexture(orderBom.getTexture());
                if(orderBom.getMaterHigh() != null){
                    orderPart.setThickness(new BigDecimal(orderBom.getMaterHigh()));
                }
            } else {
                String[] split = orderBom.getStandards().split("δ");
                if (orderBom.getTexture() != null) {
                    orderPart.setTexture(orderBom.getTexture());
                } else {
                    orderPart.setTexture(split[0]);
                }
                if (orderBom.getMaterHigh() != null) {
                    orderPart.setThickness(new BigDecimal(orderBom.getMaterHigh()));
                } else {
                    orderPart.setThickness(new BigDecimal(split[1]));
                }
            }

            orderPart.setType(2); // 普通件
            orderPart.setNetWeight(reqVo.getWeight());
            orderPart.setWorkChain(orderBom.getWorkChain()); // 工序链
            orderPart.setSource(orderBom.getReadyType()); // 备料方式：1 自制  2 外购
            orderPart.setVersionCode(1L); // 版本号
            orderPart.setMaterType(orderBom.getMaterType()); // 物料类别
            orderPart.setDrawStatus(1); // 是否制图就绪，默认 未就绪
            orderPart.setVersionNum(importMbdDxf != null ? importMbdDxf.getDocVersion() : null); // 图纸版本号
            orderPart.setDrawUpdateTime(null); // 图纸更新时间
            // orderPart.setLength(); // 宽度
            // orderPart.setWidth(); // 长度
            // orderPart.setArea(); // 面积
            // orderPart.setCritical(); // 是否关键件 0不是 1是
            orderPartMapper.insert(orderPart);
            one = orderPart;
        } else {
            OrderPart orderPart = one;
            String code = orderBom.getPlmId();
            if (code.endsWith("_170")) {
                code = code.substring(0, code.indexOf("_170"));
            }
            ImportMbdDxf importMbdDxf = importMbdDxfMapper.lambdaQuery().eq(ImportMbdDxf::getPlmid, code).orderByDesc(ImportMbdDxf::getDocVersion).last("limit 1").one();

            orderPart.setPlmId(orderBom.getPlmId());
            // orderPart.setPngUrl(); // 零件PNG图纸路径
            // orderPart.setDxfUrl(); // 零件DXF图纸路径
            orderPart.setDrawing(orderBom.getDrawing());
            if (!Objects.equals(orderBom.getMaterType(), "Platepart")) {
                orderPart.setTexture(orderBom.getTexture());
                if(orderBom.getMaterHigh() != null){
                    orderPart.setThickness(new BigDecimal(orderBom.getMaterHigh()));
                }
            } else {
                String[] split = orderBom.getStandards().split("δ");
                if (orderBom.getTexture() != null) {
                    orderPart.setTexture(orderBom.getTexture());
                } else {
                    orderPart.setTexture(split[0]);
                }
                if (orderBom.getMaterHigh() != null) {
                    orderPart.setThickness(new BigDecimal(orderBom.getMaterHigh()));
                } else {
                    orderPart.setThickness(new BigDecimal(split[1]));
                }
            }

            orderPart.setType(2); // 普通件
            orderPart.setNetWeight(reqVo.getWeight());
            orderPart.setWorkChain(orderBom.getWorkChain()); // 工序链
            orderPart.setSource(orderBom.getReadyType()); // 备料方式：1 自制  2 外购
            orderPart.setVersionCode(1L); // 版本号
            orderPart.setMaterType(orderBom.getMaterType()); // 物料类别
            orderPart.setDrawStatus(1); // 是否制图就绪，默认 未就绪
            orderPart.setVersionNum(importMbdDxf != null ? importMbdDxf.getDocVersion() : null); // 图纸版本号
            orderPart.setDrawUpdateTime(null); // 图纸更新时间
            // orderPart.setLength(); // 宽度
            // orderPart.setWidth(); // 长度
            // orderPart.setArea(); // 面积
            // orderPart.setCritical(); // 是否关键件 0不是 1是
            orderPartMapper.updateById(orderPart);
        }

        if(order.getOrderStatus() <= 3){
            return ;
        }

        if (order.getOrderStatus() < 6) {
            order.setOrderStatus(3);
            orderMapper.updateById(order);
            return ;
        }

        List<ApsWorkOrder> oldWorkOrderList = apsWorkOrderMapper.lambdaQuery().eq(ApsWorkOrder::getBomId, orderBom.getId()).list();
        List<ApsOrder> apsOrderList = apsOrderMapper.lambdaQuery().eq(ApsOrder::getOrderId, order.getId()).list();
        Map<Integer, ApsOrder> apsOrderMap = apsOrderList.stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity()));

        for (ApsWorkOrder apsWorkOrder : oldWorkOrderList) {
            ApsOrder apsOrder = apsOrderMap.get(apsWorkOrder.getApsOrderId());

            apsWorkOrder.setWorkOrderCode(orderBom.getWorkOrderCode());
            apsWorkOrder.setMaterName(orderBom.getMaterName());
            apsWorkOrder.setMaterCode(orderBom.getMaterCode());
            apsWorkOrder.setPlmId(orderBom.getPlmId());
            apsWorkOrder.setPartCount(orderBom.getPartCount());
            apsWorkOrder.setMaterHigh(orderBom.getMaterHigh());
            apsWorkOrder.setTexture(orderBom.getTexture());
            apsWorkOrder.setStandards(orderBom.getStandards());
            apsWorkOrder.setReadyType(orderBom.getReadyType());
            apsWorkOrder.setMaterType(orderBom.getMaterType());
            apsWorkOrder.setMaterWeight(orderBom.getMaterWeight());
            apsWorkOrder.setDrawing(orderBom.getDrawing());
            apsWorkOrder.setWorkChain(orderBom.getWorkChain());
            apsWorkOrder.setAssemblyPath(orderBom.getAssemblyPath());
            apsWorkOrder.setTotalCount(orderBom.getTotalCount());
            apsWorkOrder.setOrderCount(orderBom.getTotalCount().multiply(new BigDecimal(apsOrder.getOrderQty())));
            apsWorkOrderMapper.updateById(apsWorkOrder);

        }

        if(!orderBom.getWorkChain().equals(oldBom.getWorkChain()) && orderBom.getWorkChain().equals("WL")){
            // 发送到立体库
            wmsService.partProcurement(order.getId(), 0);
        } else if (!orderBom.getWorkChain().equals(oldBom.getWorkChain()) && oldBom.getWorkChain().equals("WL")){
            // 删除立体库的记录，并且清除领单号和领料顺序号
            if (CollUtil.isNotEmpty(oldWorkOrderList)) {
                List<MesPicking> pickList = oldWorkOrderList.stream().map(e -> {
                    MesPicking p = new MesPicking();
                    p.setPickListNo(Long.valueOf(e.getPickCode()));
                    p.setPickListItemNo(e.getPickSeq());
                    return p;
                }).collect(Collectors.toList());
                try {
                    Result result = wmsLtkApiClient.deletePickIng(pickList);
                    log.info("立体库删除外购件领料单结果：", result);

                    if (result.getCode() == 0) {
                        apsWorkOrderMapper.lambdaUpdate()
                                .in(ApsWorkOrder::getId, oldWorkOrderList.stream().map(ApsWorkOrder::getId).collect(Collectors.toList()))
                                .set(ApsWorkOrder::getPickCode, null)
                                .set(ApsWorkOrder::getPickSeq, null)
                                .update();
                    }
                } catch (Exception e) {
                    log.error("立体库删除外购件领料单异常：", e);
                }
            }
        }





        /*

        OrderBom orderBom = orderBomMapper.selectById(reqVo.getId());

        if (orderBom == null) {
            throw SyExceptionUtils.e("订单BOM不存在");
        }

//        if(!orderBom.getMaterType().equals("Platepart")){
//            throw SyExceptionUtils.e("只有零件可以修改BOM");
//        }

        Order order = orderMapper.selectById(orderBom.getOrderId());

//        if (orderBom.getPid() == null && (order.getOrderType().equals(3) || order.getOrderType().equals(4))) {
//            throw SyExceptionUtils.e("订单类型为工装订单或者外揽的订单不允许修改BOM");
//        }

        if (reqVo.getPartCount() != null && !reqVo.getPartCount().equals(orderBom.getPartCount())) {
            orderBom.setPartCount(reqVo.getPartCount());

            if(orderBom.getPid() != null){
                OrderBom parent = orderBomMapper.selectById(orderBom.getPid());
                orderBom.setTotalCount(parent.getTotalCount().multiply(reqVo.getPartCount()));
            } else {
                orderBom.setTotalCount(reqVo.getPartCount());
            }

            List<OrderBom> children = orderBomMapper.lambdaQuery().eq(OrderBom::getPid, orderBom.getId()).list();
            Map<Integer, OrderBom> parent = new HashMap<>();
            parent.put(orderBom.getId(), orderBom);

            while(CollUtil.isNotEmpty(children)){
                List<OrderBom> temp = new ArrayList<>();
                for(OrderBom child : children){
                    OrderBom p = parent.get(child.getPid());
                    child.setPartCount(child.getPartCount().multiply(p.getPartCount()));
                    parent.put(child.getId(), child);
                    temp.add(child);
                }

                if(CollUtil.isNotEmpty(temp)){
                    children = orderBomMapper.lambdaQuery().in(OrderBom::getPid, temp.stream().map(BaseEntity::getId).collect(Collectors.toList())).list();
                }
            }

            for (OrderBom value : parent.values()) {
                orderBomMapper.updateById(value);
            }

        }

        if(reqVo.getMaterHigh() != null){
            orderBom.setMaterHigh(reqVo.getMaterHigh());
        }

        if(reqVo.getWeight() != null){
            orderBom.setMaterWeight(reqVo.getWeight());
        }

        if (StringUtils.hasText(reqVo.getTexture())) {
            orderBom.setTexture(reqVo.getTexture());
        }

        orderBomMapper.updateById(orderBom);

        OrderPart one = orderPartMapper.lambdaQuery().eq(OrderPart::getPlmId, orderBom.getPlmId()).one();
        if(one != null){
            if(orderBom.getMaterHigh() != null){
                one.setThickness(new BigDecimal(orderBom.getMaterHigh()));
            }
            one.setNetWeight(orderBom.getMaterWeight());
            one.setTexture(orderBom.getTexture());
            orderPartMapper.updateById(one);
        }


        // 判断有没有工序，如果没有则返回
        List<OrderPhase> phaseList = orderPhaseMapper.lambdaQuery()
                .eq(OrderPhase::getOrderId, order.getId())
                .eq(OrderPhase::getBomId, orderBom.getId())
                .list();

        if (orderBom.getReadyType() != 2) {
            ProcessChain pc = processChainMapper.lambdaQuery().eq(ProcessChain::getId, reqVo.getProcessChainId()).one();
            if (pc != null && !pc.getMyCode().equals(orderBom.getWorkChain())) {
                if(order.getOrderStatus() >= 3){
                    throw SyExceptionUtils.e("订单已排产，不能修改工序");
                }

                for (OrderPhase orderPhase : phaseList) {
                    orderPhaseMapper.deleteRealById(orderPhase.getId());
                }

                List<ProcessChainItem> itemList = processChainItemMapper.lambdaQuery().eq(ProcessChainItem::getChainId, reqVo.getProcessChainId()).orderByAsc(ProcessChainItem::getSeq).list();
                List<OrderPhase> collect = itemList.stream()
                        .map(e -> {
                            OrderPhase item = new OrderPhase();
                            item.setBomId(orderBom.getId());
                            item.setOrderId(orderBom.getOrderId());
                            item.setWorkChain(orderBom.getWorkChain());
                            item.setPhaseName(e.getName());
                            item.setPhaseCode(e.getMyCode());
                            item.setPhaseSeq(e.getSeq());
                            item.setMaterNo(orderBom.getMaterCode());
                            item.setMaterName(orderBom.getMaterName());
                            return item;
                        })
                        .collect(Collectors.toList());

                orderPhaseMapper.insertBatchSomeColumn(collect);

                orderBom.setWorkChain(pc.getMyCode());
                orderBomMapper.updateById(orderBom);
                phaseList = collect;
            }
        }







        // 没有工序则返回
        if(CollUtil.isEmpty(phaseList)){
            return ;
        }

        // 未排产时，不需要管理后续操作
        if(order.getOrderStatus() < 5){
            return ;
        }

        // 如果已排产，则修改WorkOrder和WorkOrderDetail的数量
        List<ApsWorkOrder> workOrderList = apsWorkOrderMapper.lambdaQuery()
                .eq(ApsWorkOrder::getOrderId, order.getId())
                .eq(ApsWorkOrder::getBomId, orderBom.getId())
                .list();

        if(CollUtil.isEmpty(workOrderList)){
            return ;
        }
        List<Integer> apsOrderIds = workOrderList.stream().map(ApsWorkOrder::getApsOrderId).distinct().collect(Collectors.toList());
        List<ApsOrder> apsOrderList = apsOrderMapper.selectBatchIds(apsOrderIds);
        Map<Integer, ApsOrder> apsOrderMap = apsOrderList.stream().collect(Collectors.toMap(ApsOrder::getId, Function.identity()));

        for (ApsWorkOrder apsWorkOrder : workOrderList) {
            apsWorkOrder.setTotalCount(apsWorkOrder.getTotalCount());
            ApsOrder apsOrder = apsOrderMap.get(apsWorkOrder.getApsOrderId());
            apsWorkOrder.setOrderCount(new BigDecimal(apsOrder.getOrderQty()).multiply(apsWorkOrder.getTotalCount()));
            apsWorkOrder.setStandards(orderBom.getStandards());
            apsWorkOrder.setMaterHigh(orderBom.getMaterHigh());
            apsWorkOrder.setMaterWeight(orderBom.getMaterWeight());
            apsWorkOrder.setTexture(orderBom.getTexture());
            apsWorkOrderMapper.updateById(apsWorkOrder);
        }
        List<Integer> apsWorkOrderIdList = workOrderList.stream().map(BaseEntity::getId).collect(Collectors.toList());
        List<ApsWorkDetail> workDetailList = apsWorkDetailMapper.lambdaQuery()
                .in(ApsWorkDetail::getApsWorkOrderId, apsWorkOrderIdList)
                .list();

        if (CollUtil.isEmpty(workDetailList)) {
            return;
        }

        Map<Integer, ApsWorkOrder> workOrderMap = workOrderList.stream().collect(Collectors.toMap(ApsWorkOrder::getId, Function.identity()));

        for (ApsWorkDetail apsWorkDetail : workDetailList) {
            ApsWorkOrder apsWorkOrder = workOrderMap.get(apsWorkDetail.getApsWorkOrderId());
            apsWorkDetail.setTotalCount(apsWorkOrder.getOrderCount());
            apsWorkDetailMapper.updateById(apsWorkDetail);
        }

        if(order.getOrderStatus() < 7){
            return ;
        }

        // 如果大于7的时候，修改套料计划
        List<SinoCamPushDrawing> drawingList = sinoCamPushDrawingMapper.lambdaQuery()
                .eq(SinoCamPushDrawing::getOrderId, order.getId())
                .eq(SinoCamPushDrawing::getPartId, orderBom.getPlmId())
                .list();

        for (SinoCamPushDrawing sinoCamPushDrawing : drawingList) {
            sinoCamPushDrawing.setStatus(2);
            String[] split = orderBom.getStandards().split("δ");

            sinoCamPushDrawing.setNorm(orderBom.getStandards());

            if (!StringUtils.hasText(orderBom.getTexture())) {
                sinoCamPushDrawing.setTexture(split[0].trim());
            } else {
                sinoCamPushDrawing.setTexture(orderBom.getTexture());
            }
            if (orderBom.getMaterHigh() == null) {
                sinoCamPushDrawing.setThickNess(new BigDecimal(split[1].trim()));
            } else {
                sinoCamPushDrawing.setThickNess(new BigDecimal(orderBom.getMaterHigh()));
            }
            sinoCamPushDrawingMapper.updateById(sinoCamPushDrawing);
        }

        List<SinoCamPushPlan> planList = sinoCamPushPlanMapper.lambdaQuery()
                .eq(SinoCamPushPlan::getOrderId, order.getId())
                .in(SinoCamPushPlan::getNestPlanId, workDetailList.stream().map(e -> e.getId().toString()).distinct().collect(Collectors.toList()))
                .list();
        if(CollUtil.isEmpty(planList)){
            return ;
        }

        Map<Integer, ApsWorkDetail> detailMap = workDetailList.stream().filter(e -> e.getPhaseCode().equals("JG") || e.getPhaseCode().equals("HG")).collect(Collectors.toMap(e -> e.getId(), Function.identity()));
        for (SinoCamPushPlan pushPlan : planList) {
            ApsWorkDetail apsWorkDetail = detailMap.get(Integer.parseInt(pushPlan.getNestPlanId()));
            pushPlan.setPlanAmount(apsWorkDetail.getTotalCount());
            pushPlan.setStatus(2);
            sinoCamPushPlanMapper.updateById(pushPlan);
        }

        */
    }

    @Transactional
    public void bomDel(List<Integer> ids) {
        if (CollUtil.isEmpty(ids)) {
            return;
        }

//        Order order = orderMapper.selectById(orderBom.getOrderId());
//        if (order.getOrderStatus() >= 3) {
//            throw SyExceptionUtils.e("节点禁止删除!");
//        }
//
//        if (order.getOrderStatus() >= 8) {
//            throw SyExceptionUtils.e("状态不正确，无法删除");
//        }

        List<OrderBom> orderBomList = orderBomMapper.lambdaQuery().in(OrderBom::getId, ids).list();
        List<Integer> orderIds = orderBomList.stream().map(OrderBom::getOrderId).distinct().collect(Collectors.toList());
        List<Order> orderList = orderMapper.selectBatchIds(orderIds);
        long finishOrderCount = orderList.stream().filter(e -> e.getOrderStatus() >= 9).count();
        if (finishOrderCount > 0) {
            throw SyExceptionUtils.e("订单已完成或者关闭，无法删除");
        }

        List<Integer> bomIdList = orderBomList.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList());
        List<OrderPhase> orderPhaseList = orderPhaseMapper.lambdaQuery().in(OrderPhase::getBomId, bomIdList).list();
        Map<Integer, List<OrderPhase>> orderPhaseBomMap = orderPhaseList.stream().collect(Collectors.groupingBy(OrderPhase::getBomId));

        Map<Integer, Order> orderMap = orderList.stream().collect(Collectors.toMap(BaseEntity::getId, e -> e));

        List<ApsWorkOrder> apsWorkOrderList = apsWorkOrderMapper.lambdaQuery().in(ApsWorkOrder::getBomId, bomIdList).list();

        for (OrderBom bom : orderBomList) {
            Integer count = orderBomMapper.lambdaQuery().eq(OrderBom::getPid, bom.getId()).count();
            if (count > 0) {
                throw SyExceptionUtils.e("有子节点，无法删除");
            }

            if (bom.getPid() == null) {
                throw SyExceptionUtils.e("根节点无法删除");
            }

            orderBomMapper.deleteByBomId(bom.getId());
            orderPhaseMapper.deleteByBomId(bom.getId());

            Order order = orderMap.get(bom.getOrderId());
            if (order.getOrderStatus() < 4) {
                continue;
            }

            if (order.getOrderStatus() < 6) {
                order.setOrderStatus(3);
                orderMapper.updateById(order);
                continue;
            }

            apsWorkOrderMapper.deleteBomId(bom.getId());
            List<OrderPhase> orderPhases = orderPhaseBomMap.get((bom.getId()));
            for (OrderPhase orderPhase : orderPhases) {
                List<ApsWorkDetail> list = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getPhaseId, orderPhase.getId()).list();
                if(CollUtil.isNotEmpty(list)){
                    List<Integer> apsWorkDetailId = list.stream().map(BaseEntity::getId).collect(Collectors.toList());
                    for (Integer workDetailId : apsWorkDetailId) {
                        workDetailTaskMapper.deleteByWorkDetailId(workDetailId);
                    }

                }
                apsWorkDetailMapper.deleteByPhaseId(orderPhase.getId());
                apsDetailWeekdayMapper.deleteByPhaseId(orderPhase.getId());
            }
//            workDetailTaskMapper.deleteByWorkDetailId();
        }

        List<ApsWorkOrder> wlWorkOrderList = apsWorkOrderList.stream().filter(e -> e.getWorkChain().equals("WL")).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(wlWorkOrderList)) {
            // 删除立体库的信息
            List<MesPicking> pickList = wlWorkOrderList.stream().map(e -> {
                MesPicking p = new MesPicking();
                p.setPickListNo(Long.valueOf(e.getPickCode()));
                p.setPickListItemNo(e.getPickSeq());
                return p;
            }).collect(Collectors.toList());
            try {
                Result result = wmsLtkApiClient.deletePickIng(pickList);
                log.info("立体库删除外购件领料单结果：", result);
            } catch (Exception e) {
                log.error("立体库删除外购件领料单异常：", e);
            }
        }
    }

    @Transactional
    public void phaseEdit(ChangePhaseEditReqVo reqVo) {

        if(reqVo.getApsWorkTime() == null ){
            throw SyExceptionUtils.e("APS工时不能为空");
        }

        if(!StringUtils.hasText(reqVo.getApsGroupCode())){
            throw SyExceptionUtils.e("APS工作组不能为空");
        }

        if(!StringUtils.hasText(reqVo.getApsPhaseCode())){
            throw SyExceptionUtils.e("APS工序不能为空");
        }

        if(!StringUtils.hasText(reqVo.getApsPhaseName())){
            throw SyExceptionUtils.e("APS工序名称不能为空");
        }

        List<Phase> phaseList = phaseMapper.lambdaQuery().isNotNull(Phase::getMyCode).isNotNull(Phase::getName).list();

        Map<String, Phase> phaseMap = phaseList.stream().collect(Collectors.toMap(Phase::getMyCode, e -> e));
        OrderPhase preOrderPhase = orderPhaseMapper.selectById(reqVo.getPreId());
        List<OrderPhase> orderPhaseList = new ArrayList<>();
        if(preOrderPhase == null){
            OrderPhase orderPhase = orderPhaseMapper.selectById(reqVo.getId());
            orderPhaseList = orderPhaseMapper.lambdaQuery().eq(OrderPhase::getBomId, orderPhase.getBomId()).list();
        } else {
            orderPhaseList = orderPhaseMapper.lambdaQuery()
                    .eq(OrderPhase::getBomId, preOrderPhase.getBomId())
                    .gt(OrderPhase::getPhaseSeq, preOrderPhase.getPhaseSeq())
                    .list();
        }


        OrderPhase currentPhase = null;
        if(reqVo.getId() == null){
            // 新增工序
            orderPhaseMapper.lambdaUpdate()
                    .eq(OrderPhase::getBomId, preOrderPhase.getBomId())
                    .gt(OrderPhase::getPhaseSeq, preOrderPhase.getPhaseSeq())
                    .setSql("phase_seq = phase_seq + 1")
                    .update();

            Phase phase = phaseMap.get(reqVo.getApsPhaseCode());

            OrderPhase op = new OrderPhase();
            op.setPhaseCode(reqVo.getApsPhaseCode());
            op.setPhaseName(phase.getName());
            op.setPhaseSeq(preOrderPhase.getPhaseSeq() + 1);
            op.setWorkGroupNumber(reqVo.getApsGroupCode());
            op.setOpCode(reqVo.getErpGroupCode());
            op.setOp(reqVo.getErpPhaseCode());
            op.setWorkTime(new BigDecimal(reqVo.getApsWorkTime()).multiply(new BigDecimal(60)).setScale(0, RoundingMode.HALF_UP).intValue());
            if(StringUtils.hasText(reqVo.getErpWorkTime())){
                op.setOriWorkTime(new BigDecimal(reqVo.getErpWorkTime()).multiply(new BigDecimal(60)).setScale(0, RoundingMode.HALF_UP).intValue());
            }
            op.setMaterNo(preOrderPhase.getMaterNo());
            op.setMaterName(preOrderPhase.getMaterName());
            op.setOrderId(preOrderPhase.getOrderId());
            op.setBomId(preOrderPhase.getBomId());
            orderPhaseMapper.insert(op);
            currentPhase = op;
        } else {
            Phase phase = phaseMap.get(reqVo.getApsPhaseCode());
            currentPhase = orderPhaseMapper.selectById(reqVo.getId());
            currentPhase.setPhaseCode(reqVo.getApsPhaseCode());
            currentPhase.setPhaseName(phase.getName());
            currentPhase.setWorkGroupNumber(reqVo.getApsGroupCode());
            currentPhase.setOpCode(reqVo.getErpGroupCode());
            currentPhase.setOp(reqVo.getErpPhaseCode());
            currentPhase.setWorkTime(new BigDecimal(reqVo.getApsWorkTime()).multiply(new BigDecimal(60)).setScale(0, RoundingMode.HALF_UP).intValue());
            if(StringUtils.hasText(reqVo.getErpWorkTime())) {
                currentPhase.setOriWorkTime(new BigDecimal(reqVo.getErpWorkTime()).multiply(new BigDecimal(60)).setScale(0, RoundingMode.HALF_UP).intValue());
            }
            orderPhaseMapper.updateById(currentPhase);
        }

        List<OrderPhase> allPhaseList = orderPhaseMapper.lambdaQuery().eq(OrderPhase::getBomId, currentPhase.getBomId()).list();
        Order order = orderMapper.selectById(currentPhase.getOrderId());

        Map<String, Integer> phaseCount = new HashMap<>();
        StringBuilder workChain = new StringBuilder();
        for (OrderPhase phase : allPhaseList) {
            if(phase.getPhaseCode().equals("LL") || phase.getPhaseCode().equals("KJ")){
                continue;
            }
            String str = phase.getPhaseCode();
            Integer count = phaseCount.compute(str, (k, v) -> v == null ? 0 : v + 1);
            String phaseCodeCount = str + "-";
            if (count > 0) {
                phaseCodeCount = str + String.format("%02d", count) + "-";
            }

            workChain.append(phaseCodeCount);
        }

        if(workChain.toString().endsWith("-")){
            workChain.deleteCharAt(workChain.length() -1);
        }

        orderPhaseMapper.lambdaUpdate().eq(OrderPhase::getBomId, currentPhase.getBomId()).set(OrderPhase::getWorkChain, workChain.toString()).update();
        orderBomMapper.lambdaUpdate().eq(OrderBom::getId, currentPhase.getBomId()).set(OrderBom::getWorkChain, workChain.toString()).update();

        if(order.getOrderStatus() < 3){
            return ;
        }

        if(order.getOrderStatus() < 6){
            orderMapper.lambdaUpdate().eq(Order::getId, order.getId()).set(Order::getOrderStatus, 3).update();
            return ;
        }

        OrderBom bom = orderBomMapper.selectById(currentPhase.getBomId());
        Group group = groupMapper.lambdaQuery().eq(Group::getMyCode, currentPhase.getWorkGroupNumber()).one();


//        List<StationGroup> stationGroupList = stationGroupMapper.lambdaQuery().in(StationGroup::getGroupId, group.getId()).list();
//        List<Station> stationListTemp = stationMapper.selectBatchIds(stationGroupList.stream().map(StationGroup::getStationId).distinct().collect(Collectors.toList()));
        List<Station> stationListTemp = stationMapper.lambdaQuery().eq(Station::getGroupId, group.getId()).list();
        Map<Integer, List<Station>> stationGroupIdMap = stationListTemp.stream().collect(Collectors.groupingBy(Station::getGroupId));
        Map<Integer, Group> ttt = Stream.of(group).collect(Collectors.toMap(e -> e.getId(), Function.identity()));
        Map<String, List<Station>> map = stationListTemp.stream().collect(Collectors.groupingBy(e -> ttt.get(e.getGroupId()).getMyCode()));
//        Map<Integer, List<StationGroup>> stationGroupMap = stationGroupList.stream().collect(Collectors.groupingBy(StationGroup::getGroupId));


        // 新增或者修改apsWorkDetail
        if (reqVo.getId() == null) {
            List<ApsWorkDetail> apsWorkDetails = new ArrayList<>();
            List<ApsWorkOrder> apsWorkOrders = apsWorkOrderMapper.lambdaQuery().eq(ApsWorkOrder::getBomId, bom.getId()).list();
            for (ApsWorkOrder workOrder : apsWorkOrders){

                workOrder.setWorkChain(bom.getWorkChain());
                workOrder.setMaterType(bom.getMaterType());
                workOrder.setReadyType(bom.getReadyType());
                apsWorkOrderMapper.updateById(workOrder);

                List<Integer> phaseIds = orderPhaseList.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList());
                if(CollUtil.isNotEmpty(phaseIds)){
                    apsWorkDetailMapper.lambdaUpdate()
                            .in(ApsWorkDetail::getPhaseId, phaseIds)
                            .setSql("phase_seq = phase_seq + 1")
                            .update();
                }

//                List<OrderPhase> phaseList1 = phaseMap.get(workOrder.getBomId());
//                phaseList1.sort(Comparator.comparing(OrderPhase::getPhaseSeq).reversed());

                ApsOrder apsOrder = apsOrderMapper.selectById(workOrder.getApsOrderId());

                ApsWorkDetail apsWorkDetail = new ApsWorkDetail();
                apsWorkDetail.setOrderId(order.getId());
                apsWorkDetail.setApsOrderId(workOrder.getApsOrderId());
                apsWorkDetail.setApsWorkOrderId(workOrder.getId());
                apsWorkDetail.setApsWorkOrderPid(workOrder.getPid());


                if (projectConfig.getIgnorePhaseCodeList().contains(currentPhase.getPhaseCode())) {
                    continue;
                }

                apsWorkDetail.setPhaseId(currentPhase.getId());
                apsWorkDetail.setWorkTime(currentPhase.getWorkTime());

                apsWorkDetail.setPhaseSeq(currentPhase.getPhaseSeq());
                apsWorkDetail.setPhaseCode(currentPhase.getPhaseCode());
                apsWorkDetail.setPhaseName(currentPhase.getPhaseName());
                apsWorkDetail.setPhaseCode(currentPhase.getPhaseCode());
                apsWorkDetail.setMaterNo(currentPhase.getMaterNo());
                apsWorkDetail.setMaterName(currentPhase.getMaterName());
                apsWorkDetail.setPlmId(bom.getPlmId());
                apsWorkDetail.setGroupCode(currentPhase.getWorkGroupNumber());
                apsWorkDetail.setOrderType(order.getOrderType());

                // 从倒排表里取
                apsWorkDetail.setPartCount(bom.getPartCount());
                apsWorkDetail.setTotalCount(workOrder.getOrderCount());
                apsWorkDetail.setGroupId(group.getId());
                apsWorkDetail.setProcessCount(new BigDecimal(0));
                apsWorkDetail.setFinishCount(new BigDecimal(0));
                apsWorkDetail.setStatus(1);


                apsWorkDetail.setDetailSeq(null);
                apsWorkDetail.setApsOrderId(workOrder.getApsOrderId());

                apsWorkDetail.setTotalWorkTime(apsWorkDetail.getTotalCount().multiply(new BigDecimal(currentPhase.getWorkTime())).intValue());

                apsWorkDetail.setReverseDetailId(null);
                apsWorkDetail.setAppendFlag(2);
                apsWorkDetail.setPlanEndDateTime(workOrder.getPlanStartDateTime());
                apsWorkDetail.setPlanStartDateTime(apsWorkDetail.getPlanEndDateTime().minusSeconds( apsWorkDetail.getTotalWorkTime()));
                apsWorkDetails.add(apsWorkDetail);

            }

//            Map<String, List<Station>> map = new HashMap<>();
//            Map<Integer, Group> groupMap = Stream.of(group).collect(Collectors.toMap(e -> e.getId(), e->e));
//            for (StationGroup stationGroup : stationGroupList) {
//                Group g = groupMap.get(stationGroup.getGroupId());
//                if(g == null){
//                    continue;
//                }
//                List<Station> stationList = map.computeIfAbsent(g.getMyCode(), k -> new ArrayList<>());
//                Station station = stationMap.get(stationGroup.getStationId());
//                stationList.add(station);
//            }


            List<ApsWorkDetail> collect12 = apsWorkDetails.stream()
                    .flatMap(e -> {

                        List<Station> stationList = map.get(e.getGroupCode());
                        int smallTransfer = stationList.get(0).getSmallTransfer() == null ? 0 : stationList.get(0).getSmallTransfer();

                        if (CollUtil.isEmpty(stationList)) {
                            throw SyExceptionUtils.e("{}没有工位", e.getGroupCode());
                        }
                        e.setStationId(stationList.get(0).getId());

                        if (smallTransfer <= 0) {
                            return Stream.of(e);
                        }

                        int div = e.getTotalCount().divide(new BigDecimal(smallTransfer), 0, RoundingMode.DOWN).intValue();

                        BigDecimal subtract = e.getTotalCount().subtract(new BigDecimal(smallTransfer).multiply(new BigDecimal(div)));


                        List<ApsWorkDetail> l = new ArrayList<>();

                        for (int i = 0; i < div; i++) {
                            ApsWorkDetail apsWorkDetail = MkBeanUtils.copyProperties(e, ApsWorkDetail.class);
                            apsWorkDetail.setTotalCount(new BigDecimal(smallTransfer));
                            apsWorkDetail.setStationId(stationList.get(0).getId());
                            l.add(apsWorkDetail);
                        }

                        if (subtract.compareTo(BigDecimal.ZERO) > 0) {
                            ApsWorkDetail apsWorkDetail = MkBeanUtils.copyProperties(e, ApsWorkDetail.class);
                            apsWorkDetail.setTotalCount(subtract);
                            apsWorkDetail.setStationId(stationList.get(0).getId());
                            l.add(apsWorkDetail);
                        }

                        return l.stream();

                    })
                    .collect(Collectors.toList());


            for (ApsWorkDetail apsWorkDetail : collect12) {
                apsWorkDetail.setType(2);
                apsWorkDetail.setStatus(2);
                apsWorkDetailMapper.insert(apsWorkDetail);
            }

        } else {
            List<ApsWorkDetail> list = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getPhaseId, currentPhase.getId()).orderByAsc(ApsWorkDetail::getPhaseSeq).list();
            if(CollUtil.isEmpty(list)){
                List<ApsWorkDetail> apsWorkDetails = new ArrayList<>();
                List<ApsWorkOrder> apsWorkOrders = apsWorkOrderMapper.lambdaQuery().eq(ApsWorkOrder::getBomId, bom.getId()).list();
                for (ApsWorkOrder workOrder : apsWorkOrders){

                    workOrder.setWorkChain(bom.getWorkChain());
                    workOrder.setMaterType(bom.getMaterType());
                    workOrder.setReadyType(bom.getReadyType());
                    apsWorkOrderMapper.updateById(workOrder);

                    List<Integer> phaseIds = orderPhaseList.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList());
                    apsWorkDetailMapper.lambdaUpdate()
                            .in(ApsWorkDetail::getPhaseId, phaseIds)
                            .setSql("phase_seq = phase_seq + 1")
                            .update();

//                List<OrderPhase> phaseList1 = phaseMap.get(workOrder.getBomId());
//                phaseList1.sort(Comparator.comparing(OrderPhase::getPhaseSeq).reversed());

                    ApsOrder apsOrder = apsOrderMapper.selectById(workOrder.getApsOrderId());

                    ApsWorkDetail apsWorkDetail = new ApsWorkDetail();
                    apsWorkDetail.setOrderId(order.getId());
                    apsWorkDetail.setApsOrderId(workOrder.getApsOrderId());
                    apsWorkDetail.setApsWorkOrderId(workOrder.getId());
                    apsWorkDetail.setApsWorkOrderPid(workOrder.getPid());


                    if (projectConfig.getIgnorePhaseCodeList().contains(currentPhase.getPhaseCode())) {
                        continue;
                    }

                    apsWorkDetail.setPhaseId(currentPhase.getId());
                    apsWorkDetail.setWorkTime(currentPhase.getWorkTime());

                    apsWorkDetail.setPhaseSeq(currentPhase.getPhaseSeq());
                    apsWorkDetail.setPhaseCode(currentPhase.getPhaseCode());
                    apsWorkDetail.setPhaseName(currentPhase.getPhaseName());
                    apsWorkDetail.setPhaseCode(currentPhase.getPhaseCode());
                    apsWorkDetail.setMaterNo(currentPhase.getMaterNo());
                    apsWorkDetail.setMaterName(currentPhase.getMaterName());
                    apsWorkDetail.setGroupCode(currentPhase.getWorkGroupNumber());
                    apsWorkDetail.setOrderType(order.getOrderType());
                    apsWorkDetail.setPlmId(bom.getPlmId());

                    // 从倒排表里取
                    apsWorkDetail.setPartCount(bom.getPartCount());
                    apsWorkDetail.setTotalCount(workOrder.getOrderCount());
                    apsWorkDetail.setGroupId(group.getId());
                    apsWorkDetail.setProcessCount(new BigDecimal(0));
                    apsWorkDetail.setFinishCount(new BigDecimal(0));
                    apsWorkDetail.setStatus(1);


                    apsWorkDetail.setDetailSeq(null);
                    apsWorkDetail.setApsOrderId(workOrder.getApsOrderId());
                    apsWorkDetail.setWorkTime(currentPhase.getWorkTime());
                    apsWorkDetail.setTotalWorkTime(apsWorkDetail.getTotalCount().multiply(new BigDecimal(currentPhase.getWorkTime())).intValue());

                    apsWorkDetail.setReverseDetailId(null);
                    apsWorkDetail.setAppendFlag(2);
                    apsWorkDetail.setPlanEndDateTime(workOrder.getPlanStartDateTime());
                    apsWorkDetail.setPlanStartDateTime(apsWorkDetail.getPlanEndDateTime().minusSeconds( apsWorkDetail.getTotalWorkTime()));
                    apsWorkDetails.add(apsWorkDetail);

                }

//                Map<String, List<Station>> map = new HashMap<>();
//                Map<Integer, Group> groupMap = Stream.of(group).collect(Collectors.toMap(e -> e.getId(), e->e));

//                for (StationGroup stationGroup : stationGroupList) {
//                    Group g = groupMap.get(stationGroup.getGroupId());
//                    if(g == null){
//                        continue;
//                    }
//                    List<Station> stationList = map.computeIfAbsent(g.getMyCode(), k -> new ArrayList<>());
//                    Station station = stationMap.get(stationGroup.getStationId());
//                    stationList.add(station);
//                }


                List<ApsWorkDetail> collect12 = apsWorkDetails.stream()
                        .flatMap(e -> {

                            List<Station> stationList = map.get(e.getGroupCode());
                            int smallTransfer = stationList.get(0).getSmallTransfer() == null ? 0 : stationList.get(0).getSmallTransfer();

                            if (CollUtil.isEmpty(stationList)) {
                                throw SyExceptionUtils.e("{}没有工位", e.getGroupCode());
                            }
                            e.setStationId(stationList.get(0).getId());

                            if (smallTransfer <= 0) {
                                return Stream.of(e);
                            }

                            int div = e.getTotalCount().divide(new BigDecimal(smallTransfer), 0, RoundingMode.DOWN).intValue();

                            BigDecimal subtract = e.getTotalCount().subtract(new BigDecimal(smallTransfer).multiply(new BigDecimal(div)));


                            List<ApsWorkDetail> l = new ArrayList<>();

                            for (int i = 0; i < div; i++) {
                                ApsWorkDetail apsWorkDetail = MkBeanUtils.copyProperties(e, ApsWorkDetail.class);
                                apsWorkDetail.setTotalCount(new BigDecimal(smallTransfer));
                                apsWorkDetail.setStationId(stationList.get(0).getId());
                                l.add(apsWorkDetail);
                            }

                            if (subtract.compareTo(BigDecimal.ZERO) > 0) {
                                ApsWorkDetail apsWorkDetail = MkBeanUtils.copyProperties(e, ApsWorkDetail.class);
                                apsWorkDetail.setTotalCount(subtract);
                                apsWorkDetail.setStationId(stationList.get(0).getId());
                                l.add(apsWorkDetail);
                            }

                            return l.stream();

                        })
                        .collect(Collectors.toList());


                for (ApsWorkDetail apsWorkDetail : collect12) {
                    apsWorkDetail.setType(2);
                    apsWorkDetail.setStatus(2);
                    apsWorkDetailMapper.insert(apsWorkDetail);
                }
            } else {
                for (ApsWorkDetail apsWorkDetail : list) {
                    apsWorkDetail.setGroupCode(currentPhase.getWorkGroupNumber());
                    apsWorkDetail.setGroupId(group.getId());
                    apsWorkDetail.setPhaseId(currentPhase.getId());
                    apsWorkDetail.setPhaseSeq(currentPhase.getPhaseSeq());
                    apsWorkDetail.setPhaseCode(currentPhase.getPhaseCode());
                    apsWorkDetail.setWorkTime(currentPhase.getWorkTime());
                    apsWorkDetail.setTotalWorkTime(apsWorkDetail.getTotalCount().multiply(new BigDecimal(currentPhase.getWorkTime())).intValue());
                    apsWorkDetailMapper.updateById(apsWorkDetail);
                }
            }

        }

        apsWorkOrderMapper.lambdaUpdate().eq(ApsWorkOrder::getBomId, currentPhase.getBomId()).set(ApsWorkOrder::getWorkChain, workChain.toString()).update();

        long ct = allPhaseList.stream().filter(e -> e.getWorkTime() == null || !StringUtils.hasText(e.getWorkGroupNumber())).count();
        if(ct > 0){
            return ;
        }

        Optional<OrderPhase> first = allPhaseList.stream().filter(e -> e.getPhaseCode().equals("JG") || e.getPhaseCode().equals("HG")).findFirst();
        if(!first.isPresent()){
            return ;
        }

        OrderPhase jgPhase = first.get();
        List<ApsWorkDetail> splitPhaseList = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getPhaseId, jgPhase.getId()).list();
        if (CollUtil.isEmpty(splitPhaseList)) {
            return ;
        }

        // 发送到海克思康,强制推送
        try {
            planAdd(splitPhaseList);
        } catch (Exception e) {
            log.info("补充零件推送计划异常。");
        }

        List<String> nestPlanIds = splitPhaseList.stream().map(e -> {
            return String.valueOf(e.getId());
        }).collect(Collectors.toList());

        List<SinoCamPushPlan> pushPlanList = sinoCamPushPlanMapper.lambdaQuery().in(SinoCamPushPlan::getNestPlanId, nestPlanIds).list();

        List<HexagonPackagePush> hexPushList = hexagonPackagePushMapper.lambdaQuery().eq(HexagonPackagePush::getOrderId, order.getId()).list();
        if (CollUtil.isEmpty(hexPushList)) {
            return;
        }
        NestProPushHexReqVo hexReqVo = new NestProPushHexReqVo();
        hexReqVo.setNestPlanId(nestPlanIds);
        hexReqVo.setOrderId(order.getId());
        hexReqVo.setCustName(hexPushList.get(0).getCustName());
        hexReqVo.setCustCode(hexPushList.get(0).getCustCode());
        hexReqVo.setMesOrderId(hexPushList.get(0).getMesOrderId());
        hexReqVo.setMesOrderCode(hexPushList.get(0).getMesOrderCode());


        List<ApsNestHexagonItemReqVo> items = hexPushList.stream().map(e -> {
            ApsNestHexagonItemReqVo item = new ApsNestHexagonItemReqVo();
            item.setDeliveryDate(e.getEndDate());
            item.setPkgCode(e.getPackageCode());
            return item;
        }).collect(Collectors.toList());
        hexReqVo.setItem(items);
        List<HexagonPackagePush> packagePushList = hexagonNestRule.converterAndSave(hexReqVo, pushPlanList);

        hexagonNestRule.sendToMesAll(hexReqVo, packagePushList);


//
//
////        Integer smallTransfer = stationList.get(0).getSmallTransfer() == null ? 0 : stationList.get(0).getSmallTransfer();
//
//
////        List<StationGroup> stationGroupList = stationGroupMapper.lambdaQuery().eq(StationGroup::getGroupId, group.getId()).list();
//        // 如果是激割或者火割，则推送套料
//        List<String> splitPhaseList = Arrays.asList("JG", "HG");
//        if(order.getOrderStatus() >= 6 && splitPhaseList.contains(orderPhase.getPhaseCode())){
//
//            for (ApsWorkDetail apsWorkDetail : collect) {
//
//                Map<Integer, ApsWorkOrder> workOrderMap = awoList.stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity()));
//                ApsWorkOrder apsWorkOrder = workOrderMap.get(apsWorkDetail.getApsWorkOrderId());
//
//                List<ImportMbdDxf> importMbdDxfList = importMbdDxfMapper.lambdaQuery().in(ImportMbdDxf::getPlmid, bom.getPlmId()).list();
//                Map<String, ImportMbdDxf> mbdDxfMap = importMbdDxfList.stream().collect(Collectors.toMap(ImportMbdDxf::getPlmid, Function.identity(),(a,b)->b));
//
//                List<PlateStandard> plateStandardList = plateStandardMapper.lambdaQuery().in(PlateStandard::getNorm, apsWorkOrder.getStandards()).list();
//                Map<String, List<PlateStandard>> plateStandardMap = plateStandardList.stream().collect(Collectors.groupingBy(PlateStandard::getNorm));
//
//
//                lantekNestRule.saveDraw(apsWorkOrder, order, bom, mbdDxfMap);
//
//                ApsWorkOrder pa = apsWorkOrderMapper.selectById(apsWorkOrder.getPid());
//                ApsOrder apsOrder = apsOrderMapper.selectById(pa.getApsOrderId());
//                lantekNestRule.savePlan(apsWorkDetail, order, apsOrder, apsWorkOrder, pa, plateStandardMap, mbdDxfMap);
//
//            }
//            order.setPushStatus(4);
//            orderMapper.updateById(order);
//        }
    }

    @Transactional
    public void phaseDel(ChangePhaseDelReqVo reqVo) {
        OrderPhase orderPhase = orderPhaseMapper.selectById(reqVo.getId());
        OrderBom orderBom = orderBomMapper.selectById(orderPhase.getBomId());
        List<OrderPhase> allPhaseList = orderPhaseMapper.lambdaQuery().eq(OrderPhase::getBomId, orderPhase.getBomId()).ne(OrderPhase::getId, orderPhase.getId()).list();
        List<OrderPhase> gtPhaseList = allPhaseList.stream().sorted(Comparator.comparingInt(OrderPhase::getPhaseSeq)).filter(e -> e.getPhaseSeq() > orderPhase.getPhaseSeq()).collect(Collectors.toList());

        List<ApsWorkOrder> apsWorkOrderList = apsWorkOrderMapper.lambdaQuery().eq(ApsWorkOrder::getBomId, orderBom.getId()).list();
        if(CollUtil.isNotEmpty(gtPhaseList)){
            List<Integer> phaseIdList = gtPhaseList.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList());
            apsWorkDetailMapper.lambdaUpdate()
                    .in(ApsWorkDetail::getPhaseId, phaseIdList)
                    .setSql("phase_seq = phase_seq - 1")
                    .update();

        }

        orderPhaseMapper.lambdaUpdate().eq(OrderPhase::getBomId, orderBom.getId())
                .gt(OrderPhase::getPhaseSeq, orderPhase.getPhaseSeq())
                .setSql("phase_seq = phase_seq - 1").update();


        apsDetailWeekdayMapper.deleteByPhaseId(orderPhase.getId());
        apsWorkDetailMapper.deleteByPhaseId(orderPhase.getId());
        orderPhaseMapper.deleteRealById(orderPhase.getId());



        Map<String, Integer> phaseCount = new HashMap<>();
        StringBuilder workChain = new StringBuilder();
        for (OrderPhase phase : allPhaseList) {
            if(phase.getPhaseCode().equals("LL") || phase.getPhaseCode().equals("KJ")){
                continue;
            }
            String str = phase.getPhaseCode();
            Integer count = phaseCount.compute(str, (k, v) -> v == null ? 0 : v + 1);
            String phaseCodeCount = str + "-";
            if (count > 0) {
                phaseCodeCount = str + String.format("%02d", count) + "-";
            }

            workChain.append(phaseCodeCount);
        }

        if(workChain.toString().endsWith("-")){
            workChain.deleteCharAt(workChain.length() -1);
        }

        orderBomMapper.lambdaUpdate().set(OrderBom::getWorkChain, workChain.toString()).eq(OrderBom::getId, orderBom.getId()).update();
        orderPhaseMapper.lambdaUpdate().eq(OrderPhase::getBomId, orderPhase.getBomId()).set(OrderPhase::getWorkChain, workChain.toString()).update();
//        apsWorkOrderMapper.lambdaUpdate().set(ApsWorkOrder::getWorkChain, workChain.toString()).eq(ApsWorkOrder::getBomId, orderBom.getId()).update();
        apsWorkOrderMapper.lambdaUpdate().eq(ApsWorkOrder::getBomId, orderBom.getId()).set(ApsWorkOrder::getWorkChain, workChain.toString()).update();

    }

    public void planAdd(List<ApsWorkDetail> apsWorkDetailList) {

        if (CollUtil.isEmpty(apsWorkDetailList)) {
            return;
        }

        List<Integer> orderIds = apsWorkDetailList.stream().map(ApsWorkDetail::getOrderId).collect(Collectors.toList());

        List<ApsOrder> apsOrders = apsOrderMapper.lambdaQuery().in(ApsOrder::getOrderId, orderIds).list();
        Map<Integer, ApsOrder> apsOrderIdMap = apsOrders.stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity()));

        // 取 ID
        List<ApsWorkOrder> apsWorkOrders = apsWorkOrderMapper.selectBatchIds(apsWorkDetailList.stream().map(ApsWorkDetail::getApsWorkOrderId).distinct().collect(Collectors.toList()));
        Map<Integer, ApsWorkOrder> apsWorkOrderIdMap = apsWorkOrders.stream().collect(Collectors.toMap(ApsWorkOrder::getId, Function.identity()));

        // 取 PID
        List<ApsWorkOrder> parentApsWorkOrders = apsWorkOrderMapper.selectBatchIds(apsWorkDetailList.stream().map(ApsWorkDetail::getApsWorkOrderPid).distinct().collect(Collectors.toList()));
        Map<Integer, ApsWorkOrder> apsWorkOrderPidMap = parentApsWorkOrders.stream().collect(Collectors.toMap(ApsWorkOrder::getId, Function.identity()));

        // 获取工厂信息
        List<Factory> factoryList = factoryMapper.selectList(null);
        Map<Integer, Factory> factoryMap = factoryList.stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity()));

        List<Order> orderList = orderMapper.lambdaQuery().in(BaseEntity::getId, orderIds).list();

        // 保存计划信息
        savePlan(apsWorkDetailList, factoryMap, orderList, apsOrderIdMap, apsWorkOrderPidMap, apsWorkOrderIdMap);

    }

    public void savePlan(List<ApsWorkDetail> apsWorkDetailList, Map<Integer, Factory> factoryMap, List<Order> orderList, Map<Integer, ApsOrder> apsOrderIdMap, Map<Integer, ApsWorkOrder> apsWorkOrderPidMap, Map<Integer, ApsWorkOrder> apsWorkOrderIdMap) {

        List<SinoCamPushDrawing> sinoCamPushPushDrawList = sinoCamPushDrawingMapper.lambdaQuery().in(SinoCamPushDrawing::getPartId, apsWorkDetailList.stream().map(ApsWorkDetail::getPlmId).collect(Collectors.toList())).list();
        Map<String, SinoCamPushDrawing> sinoCamPushPushDrawMap = sinoCamPushPushDrawList.stream().collect(Collectors.toMap(SinoCamPushDrawing::getPartId, Function.identity(), (a, b) -> b));

        Map<Integer, Order> orderMap = orderList.stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity()));

        List<ApsWorkOrder> allApsWorkOrder = apsWorkOrderMapper.lambdaQuery().in(ApsWorkOrder::getOrderId, orderList.stream().map(Order::getId).collect(Collectors.toList())).list();
        Map<Integer, List<ApsWorkOrder>> orderApsWorkOrder = allApsWorkOrder.stream().collect(Collectors.groupingBy(ApsWorkOrder::getOrderId));
        Map<Integer, Map<Integer, ApsWorkOrder>> allApsWorkOrderMap = new HashMap<>();
        for (Integer orderId : orderApsWorkOrder.keySet()) {
            List<ApsWorkOrder> orderApsWorkOrderMap = orderApsWorkOrder.get(orderId);
            Map<Integer, ApsWorkOrder> apsWorkOrderMap = orderApsWorkOrderMap.stream().collect(Collectors.toMap(ApsWorkOrder::getId, Function.identity()));
            allApsWorkOrderMap.put(orderId, apsWorkOrderMap);
        }

        List<SinoCamPushPlan> pushPlans = sinoCamPushPlanMapper.lambdaQuery().in(SinoCamPushPlan::getOrderId, orderList.stream().map(Order::getId).collect(Collectors.toList())).list();
        Map<String, SinoCamPushPlan> pushPlanMap = pushPlans.stream().collect(Collectors.toMap(SinoCamPushPlan::getNestPlanId, Function.identity()));

        List<SinoCamPushPlan> pushPlanList = new ArrayList<>();
        // 构建推送参数和数据库记录信息
        for (ApsWorkDetail apsWorkDetail : apsWorkDetailList) {

            SinoCamPushPlan pushPlan = new SinoCamPushPlan();

            ApsWorkOrder current = apsWorkOrderIdMap.get(apsWorkDetail.getApsWorkOrderId());
            ApsWorkOrder parent = apsWorkOrderPidMap.get(current.getPid());
            ApsOrder apsOrder = apsOrderIdMap.get(apsWorkDetail.getApsOrderId());
            Order order = orderMap.get(apsWorkDetail.getOrderId());

            int id = current.getId();
//            String path = PkgUtils.gen(apsOrder.getSeq()) + "→";
            String path = "";
            while (true) {
                Map<Integer, ApsWorkOrder> orderApsWorkOrderMap = allApsWorkOrderMap.get(order.getId());
                ApsWorkOrder pathCur = orderApsWorkOrderMap.get(id);
                if (ObjectUtils.isEmpty(pathCur) || pathCur.getPid() == null) {
//                    path = PkgUtils.gen(apsOrder.getSeq()) + path;
                    break;
                }
                ApsWorkOrder pathPar = orderApsWorkOrderMap.get(pathCur.getPid());
                path = "→" + pathPar.getPlmId() + path;
                id = pathPar.getId();
            }

            SinoCamPushDrawing pushDraw = sinoCamPushPushDrawMap.get(apsWorkDetail.getPlmId());

            pushPlan.setComponentId(parent.getPlmId());
            pushPlan.setComponentName(parent.getMaterName());
            pushPlan.setFactoryIdk(factoryMap.get(apsWorkDetail.getFactoryId()).getMyCode());
            pushPlan.setNeedDate(apsWorkDetail.getPlanStartDateTime());
            pushPlan.setNestPlanId(String.valueOf(apsWorkDetail.getId()));
            pushPlan.setPartId(current.getPlmId());
            pushPlan.setPartName(current.getMaterName());
            pushPlan.setPartType("1");
            pushPlan.setPlanAmount(apsWorkDetail.getTotalCount());
            pushPlan.setProcessingNo(PkgUtils.gen(apsOrder.getSeq()));
            pushPlan.setApsOrderId(apsWorkDetail.getApsOrderId());
            pushPlan.setProductId(StringUtils.hasText(order.getConstructNo())?order.getConstructNo():order.getOrderCode());
            pushPlan.setVersionBrief("V1");
            if (ObjectUtils.isEmpty(pushDraw) || pushDraw.getStatus() == 5) {
                pushPlan.setStatus(5);
                pushPlan.setErrorMsg("推送图纸异常。");
                pushPlan.setUniMaterCode(current.getPlmId() + "#A.0");
                pushPlan.setReplaceTexture(null);
                pushPlan.setReplaceThickness(null);
            } else {
                pushPlan.setStatus(1);
                pushPlan.setErrorMsg(null);
                pushPlan.setUniMaterCode(current.getPlmId() + "#" + pushDraw.getDrawVersion());
                pushPlan.setReplaceTexture(pushDraw.getTexture());
                pushPlan.setReplaceThickness(pushDraw.getThickNess());
            }
            pushPlan.setPlanFinishAmount(new BigDecimal(0));
            pushPlan.setOrderId(order.getId());
            pushPlan.setVersionNum(1);
            pushPlan.setConsumeStatus(0);
            pushPlan.setPath(path);

            pushPlanList.add(pushPlan);

            if (pushPlanMap.get(pushPlan.getNestPlanId()) != null) {
                sinoCamPushPlanMapper.lambdaUpdate().eq(SinoCamPushPlan::getNestPlanId, pushPlan.getNestPlanId()).set(SinoCamPushPlan::getPath, pushPlan.getPath()).update();
                pushPlanList.remove(pushPlan);
            }

        }

        if (CollUtil.isEmpty(pushPlanList)) {
            return ;
        }
        sinoCamPushPlanMapper.insertBatchSomeColumn(pushPlanList);

    }

}
